Flutter学习之布局常用控件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_18948359/article/details/81700549

简介

对于我们已经特别熟悉了前端的同学来说,HTML + CSS 来布局已经是可以各种花式操作了,但是对于 Flutter 这个框架来说,感觉就不一样了,因为 Flutter 上面已经不在使用 CSS 的那套语法了。所以就需要重新来看 Flutter 的布局。

先引用官方的一段话。点击这里跳转到官网。

重点是什么?

  • Widgets 是用于构建UI的类.
  • Widgets 用于布局和UI元素.
  • 通过简单的widget来构建复杂的widget

Flutter 布局的机制的核心就是在 widget。在 Flutter 中,几乎所有的东西都是一个 widget-甚至布局模型都是 widget。您在Flutter应用中看到的图像、图标和文本都是widget。 甚至你看不到的东西也是widget,例如行(row)、列(column)以及用来排列、约束和对齐这些可见widget的网格(grid)。

布局

图片中显示的布局结构,一个行包含3列,其中每列包含一个图标和一个标签。

以下是此UI的widget树示意图,我们可以清晰的看到 widget 的包含关系。

flutter布局组件树

布局组件

所有的布局 widget 都有一个 child 属性(例如:Center 或 Container), 或者一个children 属性,如果他们需要一个 widget 列表(例如 Row, Column, ListView 或者 Stack)

容纳可见对象的 widget

Image widget

Image 的多种构造方法

  • new Image, 通用方法,使用ImageProvider实现,如下方法本质上也是使用的这个方法
  • new Image.asset,用于使用key从AssetBundle获取图像。
  • new Image.network,用于从URL地址获取图像。
  • new Image.file,用于从File获取图像。

为了自动执行像素密度感知资源分辨率,使用AssetImage指定图像,需要确保在控件树中的图片控件上方存在MaterialApp、WidgetsApp和MediaQuery控件。

// 获取资源图片
new Image.asset('images/myPic.jpg')

// 从网络上面获取图片
new Image.network(
          'https://flutter.io/images/homepage/screenshot-2.png',
          scale: 2.0)

// 使用ImageProvider 加载图片
new Image(image: new NetWorkImage("https://flutter.io/images/homepage/screenshot-2.png"))

图片的 width 和 heigth

new Image.asset( 'imgs/logo.jpeg',  width: 200.0, height: 100.0, fit: BoxFit.fill );

在使用本地图片之前,我们需要指定本地图片的路径。在 pubspec.yaml 文件中配置

# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg

Text widget

// 新建一个展示文字的控件,通过 style: new TextStyle() 来给文字增加样式
new Text('Hello World', style: new TextStyle(fontSize: 32.0))

创建一个 Icon widget:

图标控件,图标控件是没有交互功能的,只能作为展示使用,如果需要有交互功能,可以使用 Material 中的 IconButton。

详细可以查看官方文档:https://docs.flutter.io/flutter/widgets/Icon-class.html

new Icon(Icons.star, color: Colors.red[500])

Container 组件

容器,一个常用的控件,由基本的绘制、位置和大小控件组成。负责创建矩形的可视元素,可以用BoxDecoration来设计样式,比如背景、边框和阴影,Container也有边距、填充和大小限制,另外,还可以在三维空间利用矩阵进行变换。

Container 概要

  • 添加 padding,margins,borders
  • 改变背景颜色或者图片
  • 包含单个子 widget,但是该子 widget 可以是 Row, Column, 甚至是 widget 树的根
  • 属性decoration和color无法共存
  • Container默认是尽可能大的占用空间, 但是如果你给它指定一个width,那它就会采用指定的值
import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter demo',
        home: new Container(
          decoration: new BoxDecoration(
              color: Colors.white
          ),
          child: new Center(
            child: new Text('Hello World',
                style: new TextStyle(fontSize: 20.0, color: Colors.black87)),
          ),
        )
    );
  }
}

图示
Container

Row 和 Column

最常见的布局模式之一是垂直或水平排列widget。我们可以使用行(Row)水平排列widget,并使用列(Column)垂直排列widget。

简要说明

  • 行和列是两种最常用的布局模式
  • 行和列都需要一个子widget列表
  • 子widget本身可以是行、列或其他复杂widget
  • 可以指定行或列如何在垂直或水平方向上对齐其子项
  • 可以拉伸或限制特定的子widget
  • 可以指定子widget如何使用行或列的可用空间

Row

flex水平布局控件,能够将子控件水平排列,是基于Web的flexbox的布局模式设计的。

Row子控件有灵活与不灵活的两种,Row首先列出不灵活的子控件,减去它们的总宽度,计算还有多少可用的空间。然后Row按照Flexible.flex属性确定的比例在可用空间中列出灵活的子控件。要控制灵活子控件,需要使用Expanded控件。

如果只有一个子控件,可以使用 Align or Center控件定义该子控件位置。

new Row(
  children: <Widget>[
    new Expanded(
      child: new Text('Deliver features faster', textAlign: TextAlign.center),
    ),
    new Expanded(
      child: new Text('Craft beautiful UIs', textAlign: TextAlign.center),
    ),
    new Expanded(
      child: new FittedBox(
        fit: BoxFit.contain, // otherwise the logo will be tiny
        child: const FlutterLogo(),
      ),
    ),
  ],
)

Column
flex垂直布局控件,能够将子控件垂直排列。

new Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  mainAxisSize: MainAxisSize.min,
  children: <Widget>[
    new Text('We move under cover and we move as one'),
    new Text('Through the night, we have one shot to live another day'),
    new Text('We cannot let a stray gunshot give us away'),
    new Text('We will fight up close, seize the moment and stay in it'),
    new Text('It’s either that or meet the business end of a bayonet'),
    new Text('The code word is ‘Rochambeau,’ dig me?'),
    new Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)),
  ],
)

比较复杂的布局,可以看下官网:https://flutterchina.club/tutorials/layout/

猜你喜欢

转载自blog.csdn.net/qq_18948359/article/details/81700549