Flutter学习笔记之理解widget树

  • Widget树是我们创建UI的方式,在Flutter中我们经常看到或听到这样一句话:一切皆Widget,Widget地狱嵌套。为了代码更容易理解:尽可能的保持Widget树层级较浅。
    Material Design:Widget树的属性
    Scaffold:脚手架,实现Material可视化布局
    AppBar:界面顶部实现工具栏
    CircleAvatar:显示一张圆形用户资料照片,可用于任何图片
    Divider:绘制一条具有上下边距的水平线
    SingleChildScrollView:可将垂直或水平滚动能力增加到单个子Widget上,防止屏幕溢出,内容过多时不建议使用,影响性能
    Padding:可添加上、下、左、右内边距
    Column:显示子Widget纵向列表
    Row:显示子Widget横向列表
    Container:可用于空白占位符(不可见),也可设置其它属性灵活运用
    Expanded:可填充从属于Column或Row Widget的子Widget可用空间
    Text:界面显示的文本
    Stack:层叠组件、绝对定位
    Positioned:允许设置宽高,与Stack结合使用,指定Stack Widget上、下、左、右四边的定位距离
//引入Material风格库,使用Material风格组件
import 'package:flutter/material.dart';
//创建有状态Widget
class Home extends StatefulWidget {
    
    
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
    
    
//创建变量,初始值0
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      appBar: AppBar(
        title: Text('Widget Tree'),
      ),
      body: SafeArea(//SafeArea适配屏幕安全区
        child: SingleChildScrollView(//防止Widget屏幕滚动溢出
          child: Padding(//内边距
            padding: EdgeInsets.all(16.0),//上下左右边距16
            child: Column(//纵向列表,可放置多个子Widget
              children: <Widget>[
                const RowWidget(),//Widget
                Padding(
                  padding: EdgeInsets.all(16.0),
                ),
                const RowAndColumnWidget(),//Widget
                CounterTextWidget(counter: _counter),//Widget
                TextButton(//按扭
                  child: Text('Add to Counter'),
                  //点击事件宣染界面变化值
                  onPressed: () {
    
    
                    setState(() {
    
    
                    //回调方法
                      _addToCounter();
                    });
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
//自定义方法函数
  void _addToCounter() {
    
    
    return setState(() {
    
    
      _counter++;
    });
  }
}
//构建自定义类Widget
class CounterTextWidget extends StatelessWidget {
    
    
//使用const关键字得到缓存性能优势 
  const CounterTextWidget({
    
    
    Key key,
    @required int counter,
  })  : _counter = counter,
        super(key: key);

  final int _counter;

  @override
  Widget build(BuildContext context) {
    
    
    print('CounterTextWidget $_counter');

    return Text('CounterTextWidget $_counter');
  }
}
//构建类Widget
class RowWidget extends StatelessWidget {
    
    
  const RowWidget({
    
    
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    print('RowWidget');

    return Row(
      children: <Widget>[
        Container(
          color: Colors.yellow,
          height: 40.0,
          width: 40.0,
        ),
        Padding(
          padding: EdgeInsets.all(16.0),
        ),
        Expanded(
          child: Container(
            color: Colors.amber,
            height: 40.0,
            width: 40.0,
          ),
        ),
        Padding(
          padding: EdgeInsets.all(16.0),
        ),
        Container(
          color: Colors.brown,
          height: 40.0,
          width: 40.0,
        ),
      ],
    );
  }
}
//构建类Widget
class RowAndColumnWidget extends StatelessWidget {
    
    
  const RowAndColumnWidget({
    
    
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    print('RowAndColumnWidget');

    return Row(
      children: <Widget>[
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            Container(
              color: Colors.yellow,
              height: 60.0,
              width: 60.0,
            ),
            Padding(
              padding: EdgeInsets.all(16.0),
            ),
            Container(
              color: Colors.amber,
              height: 40.0,
              width: 40.0,
            ),
            Padding(
              padding: EdgeInsets.all(16.0),
            ),
            Container(
              color: Colors.brown,
              height: 20.0,
              width: 20.0,
            ),
            Divider(),
            //调用RowAndStackWidget
            const RowAndStackWidget(),
            Divider(),
            Text('End of the Line. Date: ${DateTime.now()}'),
          ],
        ),
      ],
    );
  }
}
//构建类Widget
class RowAndStackWidget extends StatelessWidget {
    
    
  const RowAndStackWidget({
    
    
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    print('RowAndStackWidget');

    return Row(
      children: <Widget>[
        CircleAvatar(
          backgroundColor: Colors.lightGreen,
          radius: 100.0,
          child: Stack(
            children: <Widget>[
              Container(
                height: 100.0,
                width: 100.0,
                color: Colors.yellow,
              ),
              Container(
                height: 60.0,
                width: 60.0,
                color: Colors.amber,
              ),
              Container(
                height: 40.0,
                width: 40.0,
                color: Colors.brown,
              ),
            ],
          ),
        ),
      ],
    );
  }
}

  • 以上代码使用了类Widget提高代码理解可阅读性
  • 除了用类构建Widget还可以用常量与方法函数构建Widget,注意在使用常量初始化时Widget会依赖父Widget的BuildContext对象,每次重绘父Widget,常量也会重绘,因此无进行性能优化,所以不推荐使用,方法函数Widget同理,下面我看一下常量widget与方法函数Widget的写法:
//常量Widget
final container = Container(
	conlor:Colors.Blue,
	height:40,
	width:40);
//方法Widget
Widget _buildContainer(){
    
    
	return Container(
		color:Colors.Blue,
		height:40,
		width:40,
	);
   }

猜你喜欢

转载自blog.csdn.net/qq_32876451/article/details/115397656