Android技术知识Android开发Android开发经验谈

Android Flutter:那些不可忽视的基础布局!

2020-09-14  本文已影响0人  Carson带你学安卓

前言

示意图

今天,我主要讲解Flutter中布局方面的基础布局组件,主要包括:


1. Container

1.1 定义

布局容器,属于组合widget,内部有绘制widget、定位widget、尺寸widget

1.2 布局原理

由于Container结合了许多其他Widget;而每个Widget都有自己的布局行为,因此Container的布局行为十分复杂,具体介绍如下:

1.3 属性说明

Container({
    Key key, // 控制框架在widget重建时与哪些其他widget匹配
    this.alignment, // 子Widget对齐,生效范围:父Widget尺寸 > child Widget尺寸
    this.padding, // 内边距,即本Widget边框和内容区之间距离
    this.margin, // 外边距:本Widget与父边框的距离。
    Color color, // Container背景色
    Decoration decoration, // 绘制背景图案,注:container背景色和decoration不能同时设置
    this.foregroundDecoration, // 前景。设置了foregroundDecoration可能会遮盖child内容,一般半透明遮盖(蒙层)效果使用!
    double width, // container的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局。
    double height, // container的高度,设置为double.infinity可以强制在高度上撑满。
    BoxConstraints constraints, // 添加到child上额外的约束条件,用于设置child的宽高范围值
    this.child, // 控件内容widget。
  })

关于Decoratiton的使用,具体请看文章:

1.4 具体使用

import 'package:flutter/material.dart';// Material UI组件库

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

// 无状态控件显示
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// 主界面入口返回的组件 = MaterialApp
    return MaterialApp(
      title: 'Widget_Demo', //标题
      theme: ThemeData(primarySwatch: Colors.blue), //主题色
      home: MyHomePage(), // 返回一个Widget对象,用来定义当前应用打开的时候,所显示的界面
    );
  }
}

// 返回的Widget对象
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //设置appbar
        appBar: new AppBar(
          title: new Text('Flutter Demo'),
        ),
        //主体
        body: new Container(
          alignment: Alignment.center,// 对齐
          padding: const EdgeInsets.all(5.0),// 内边距
          margin: const EdgeInsets.all(10.0),// 外边距
          color: Colors.grey,// 背景色
          // 装饰(无法和color一起设置)
//          decoration: new BoxDecoration(
//            border: new Border.all(width: 2.0, color: Colors.red),
//            borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
//            image: new DecorationImage(
//              image: new AssetImage('assetImage/photo.jpg'),
//              centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
//            ),
//          ),
          // 添加到child上额外的约束条件,用于设置child的宽高范围值
          constraints: new BoxConstraints.expand(
            height: Theme
                .of(context)
                .textTheme
                .display1
                .fontSize * 1.1 + 200.0,
          ),

          // 设置子空间
          child: Text("carson ho Demo",),
        )
    );
  }
}

1.5 测试效果


2. Row

2.1 作用

水平展示多个子控件的控件,即将一系列控件排成一行显示

注:该控件无法滚动。若超过一行则会报错,应考虑使用ListView类。

2.2 概念解析:主轴 & 纵轴

对于线性布局:

2.3 属性说明

 // 属性说明
 Row({
    Key key,  // 全局key来唯一标识子widget
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,  // 子控件放置方式
    MainAxisSize mainAxisSize = MainAxisSize.max,  // 子控件应该如何沿着主轴放置
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 子控件对齐方式
    TextDirection textDirection, // 排列方式:从左到右,还是从右到左排序
    VerticalDirection verticalDirection = VerticalDirection.down,  // 垂直排序
    TextBaseline textBaseline, // 对齐文本的水平线
    List<Widget> children = const <Widget>[], // 子控件
  })

 // 属性详解
 // 1. mainAxisAlignment
 // 说明:子控件根据主轴的对齐方式,枚举对象(默认值为start)
 enum MainAxisAlignment {
  start,  // 内部的子组件将从主轴起始位置开始排列(正向排列)
   end, // 内部的子组件将从主轴末尾位置开始排列(反向排列)
  center, // 内部的子组件将从主轴中间位置开始排列(居中)
  spaceBetween, // 内部的首尾子组件靠近首尾两端,其余子组件居中排列且组件间的间距一样
  spaceAround,  // 内部的子组件居中排列,且每个子组件的左右边距一样大
  spaceEvenly,  // 内部的子组件居中显示,每个空间的左边和右边都有相同的间距
}

// 2. mainAxisSize
// 说明:子控件如何放置,枚举对象(默认值为max)
enum MainAxisSize {
  min, // 控件尽可能小,相当于wrap_content(取此值时,上面的MainAxisAlignment 无效),
  max, //  控件尽可能大,相当于match_parent
}

// 3. crossAxisAlignment
// 说明:子控件对于纵轴的对齐方式,当子控件高度不一样时,如何被放置在主轴(中心轴),而MainAxisAlignment 决定了子控件间的间隔
enum CrossAxisAlignment {
  start,  // 内部的子组件将从非主轴起始位置开始排列(正向排列)
  end, // 内部的子组件将从非主轴末尾位置开始排列(反向排列)
  center, // 内部的子组件将从非主轴中间位置开始排列(居中)
  stretch, // 内部的子组件将从非主轴中间位置开始排列,并且完全填充非主轴方向
  baseline, // 内部的子组件将从baseline的方向对齐,这个需要设置textBaseline属性,不然的话会报错
}

// 4. textBaseline
// 说明:对齐文本的水平线
enum TextBaseline {
  alphabetic, // 用于对齐字母字符的字形底部的水平线
  ideographic,  // 用于对齐表意文字的水平线
}

// 5. textDirection
// 说明:子控件排序方向 (一般不用设置,除非想反转子控件排序)
// Row 使用 TextDirection
// Column 使用 VerticalDirection
enum VerticalDirection {
  up,  //  子控件从下到上排序
  down, //  子控件从上到下排序
}
enum TextDirection {
  rtl, // 子控件从右到左排序
  ltr, // 子控件从左到右排序
}

// 6. children
// 设置子控件

2.4 具体使用

import 'package:flutter/material.dart'; // Material UI组件库

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

// 无状态控件显示
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// 主界面入口返回的组件 = MaterialApp
    return MaterialApp(
      title: 'Widget_Demo', //标题
      theme: ThemeData(primarySwatch: Colors.blue), //主题色
      home: MyHomePage(), // 返回一个Widget对象,用来定义当前应用打开的时候,所显示的界面
    );
  }
}

// 返回的Widget对象
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //设置appbar
      appBar: new AppBar(
        title: new Text('Flutter Demo'),
      ),
      //主体
      body: new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        textDirection: TextDirection.ltr,
        children: <Widget>[
          Text(" Carson Ho "),
          Text(" Kobe Bryant "),
          Text(" LeBorn James  "),
          Text(" Michael Jordan  "),
        ],
      ),
    );
  }
}

2.5 效果图


3. Column

3.1 作用

垂直方向展示多个子控件的控件,即将一系列控件排成一列显示

3.2 属性说明

属性类似于Row的属性,主要包括:

 // 属性说明
 Column({
    Key key,  // 全局key来唯一标识子widget
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,  // 子控件放置方式
    MainAxisSize mainAxisSize = MainAxisSize.max,  // 子控件应该如何沿着主轴放置
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 子控件对齐方式
    TextDirection textDirection, // 排列方式:从左到右,还是从右到左排序
    VerticalDirection verticalDirection = VerticalDirection.down,  // 垂直排序
    TextBaseline textBaseline, // 对齐文本的水平线
    List<Widget> children = const <Widget>[], // 子控件
  })

// 属性详解
 // 1. mainAxisAlignment
 // 说明:子控件根据主轴的对齐方式,枚举对象(默认值为start)
 enum MainAxisAlignment {
  start,  // 内部的子组件将从主轴起始位置开始排列(正向排列)
   end, // 内部的子组件将从主轴末尾位置开始排列(反向排列)
  center, // 内部的子组件将从主轴中间位置开始排列(居中)
  spaceBetween, // 内部的首尾子组件靠近首尾两端,其余子组件居中排列且组件间的间距一样
  spaceAround,  // 内部的子组件居中排列,且每个子组件的左右边距一样大
  spaceEvenly,  // 内部的子组件居中显示,每个空间的左边和右边都有相同的间距
}

// 2. mainAxisSize
// 说明:子控件如何放置,枚举对象(默认值为max)
enum MainAxisSize {
  min, // 控件尽可能小,相当于wrap_content(取此值时,上面的MainAxisAlignment 无效),
  max, //  控件尽可能大,相当于match_parent
}

// 3. crossAxisAlignment
// 说明:子控件对于纵轴的对齐方式,当子控件高度不一样时,如何被放置在主轴(中心轴),而MainAxisAlignment 决定了子控件间的间隔
enum CrossAxisAlignment {
  start,  // 内部的子组件将从非主轴起始位置开始排列(正向排列)
  end, // 内部的子组件将从非主轴末尾位置开始排列(反向排列)
  center, // 内部的子组件将从非主轴中间位置开始排列(居中)
  stretch, // 内部的子组件将从非主轴中间位置开始排列,并且完全填充非主轴方向
  baseline, // 内部的子组件将从baseline的方向对齐,这个需要设置textBaseline属性,不然的话会报错
}

// 4. textBaseline
// 说明:对齐文本的水平线
enum TextBaseline {
  alphabetic, // 用于对齐字母字符的字形底部的水平线
  ideographic,  // 用于对齐表意文字的水平线
}

// 5. textDirection
// 说明:子控件排序方向 (一般不用设置,除非想反转子控件排序)
// Row 使用 TextDirection
// Column 使用 VerticalDirection
enum VerticalDirection {
  up,  //  子控件从下到上排序
  down, //  子控件从上到下排序
}
enum TextDirection {
  rtl, // 子控件从右到左排序
  ltr, // 子控件从左到右排序
}

// 6. children
// 设置子控件

3.3 具体使用

import 'package:flutter/material.dart'; // Material UI组件库

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

// 无状态控件显示
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// 主界面入口返回的组件 = MaterialApp
    return MaterialApp(
      title: 'Widget_Demo', //标题
      theme: ThemeData(primarySwatch: Colors.blue), //主题色
      home: MyHomePage(), // 返回一个Widget对象,用来定义当前应用打开的时候,所显示的界面
    );
  }
}

// 返回的Widget对象
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //设置appbar
      appBar: new AppBar(
        title: new Text('Flutter Demo'),
      ),
      //主体
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        verticalDirection: VerticalDirection.down,
        children: <Widget>[
          Text(" Carson Ho "),
          Text(" Kobe Bryant "),
          Text(" LeBorn James  "),
          Text(" Michael Jordan  "),
        ],
      ),
    );
  }
}

3.4 具体效果


4. Expanded

4.1 作用

按比例伸缩 / 扩展 Row、Column和Flex子组件所占用的空间大小

4.2 属性说明

const Expanded({
    Key key, // 唯一标识符
    int flex = 1, // 弹性系数,默认值 = 1
                 // 若为 0 或 null,则 child 是没有弹性的,即不会被扩伸占用的空间。
                 // 若大于 0,所有的Expanded按照其flex的比例来分割主轴的全部空闲空间。
    @required Widget child, // 子控件
}) 

4.3 具体使用

import 'package:flutter/material.dart'; // Material UI组件库

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

// 无状态控件显示
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
// 主界面入口返回的组件 = MaterialApp
    return MaterialApp(
      title: 'Widget_Demo', //标题
      theme: ThemeData(primarySwatch: Colors.blue), //主题色
      home: MyHomePage(), // 返回一个Widget对象,用来定义当前应用打开的时候,所显示的界面
    );
  }
}

// 返回的Widget对象
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //设置appbar
      appBar: new AppBar(
        title: new Text('Flutter Demo'),
      ),
      //主体:配合Row使用(采用两个容器Container来展示)
      body: new Row(
        children: <Widget>[
          Expanded(
              flex: 2, // 占2份空间
              child: Container(
                color: Colors.red,
              )),
          Expanded(
              flex: 1, // 占1份空间
              child: Container(
                color: Colors.green,
              )),
        ],
      ),
    );
  }
}

4.4 测试效果


5. Center

中心定位控件,能够将子控件放在其内部中心

class Page extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("正中央"), // 将text放到文本中央
    );
  }
}

总结

本文全面介绍了Flutter常用的基础布局组件,总结如下:

接下来推出的文章,我将继续讲解Flutter的相关知识,包括使用语法、实战等,感兴趣的读者可以继续关注我的博客哦:Carson_Ho的Android博客


请点赞!因为你们的赞同/鼓励是我写作的最大动力!

相关文章阅读
Android开发:最全面、最易懂的Android屏幕适配解决方案
Android开发:史上最全的Android消息推送解决方案
Android开发:最全面、最易懂的Webview详解
Android开发:JSON简介及最全面解析方法!
Android四大组件:Service服务史上最全面解析
Android四大组件:BroadcastReceiver史上最全面解析


欢迎关注Carson_Ho的简书!

不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度

上一篇下一篇

猜你喜欢

热点阅读