美文网首页Flutter
【Flutter】开发之基础Widget(三)

【Flutter】开发之基础Widget(三)

作者: 欢子3824 | 来源:发表于2019-05-17 18:00 被阅读168次

    什么是 Widget

    Flutter 的核心设计思想便是一切即 Widget,在 Flutter 的世界里,包括viewsviewcontrollerslayouts等在内的概念都建立在 Widget 之上,可以理解成原生的View

    lib/main.dart 是程序的主入口

    //导包
    import 'package:flutter/material.dart';
    //程序入口
    void main() => runApp(MyApp());
    //相当于主页面
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue, 
          ),
          home: MyHomePage(title: 'Home Page'),
        );
      }
    }
    

    可以看到,这个返回了一个MaterialAppWidget,作为程序的主界面。

    父级组件

    Widget 介绍
    StatelessWidget 无状态widget,类似静态页面,不与用户交互
    StatefulWidget 有状态widget,可以改变,可以与用户交互

    基础组件

    Widget 介绍
    MaterialApp 一般用作APP顶层的主页入口,可配置主题,多语言,路由等
    Scaffold 一般用户页面的承载Widget,包含appbar、snackbar、drawer等material design的设定。
    Appbar 一般用于Scaffold的appbar ,内有标题,二级页面返回按键等,当然不止这些,tabbar等也会需要它
    Text 显示文本,类似于TextView
    Image 显示图片,可以加载本地资源、file、网络图片、内存图片
    TextField 输入框,类似于EditText
    • Text
              Text(
              //文本
              '我是Text我是Text我是Text我是Text我是Text我是Text我是Text我是Text我是Text我是Text',
              //超出屏幕 clip裁剪,fade渐隐,ellipsis省略号
              overflow: TextOverflow.ellipsis,
              //对齐方式
              textAlign: TextAlign.center,
              //文本方向
              textDirection: TextDirection.rtl,
              //样式
              style: TextStyle(
                color: Colors.lightBlue,
                fontSize: 14,
                fontStyle: FontStyle.italic,
                backgroundColor: Colors.black87,
                //none无文字装饰,lineThrough删除线,overline文字上面显示线,underline文字下面显示线
                decoration: TextDecoration.lineThrough,
                //字母间隙
                letterSpacing: 10,
              ),
            )
    
    image.png
    • Image
    方法 作用
    Image.assetImage(image: new AssetImage() 加载本地图片
    Image.fileImage(image: new FileImage() file
    Image.memoryImage(image: new MemoryImage() 加载内存byte数组
    Image.networkImage(image: new NetworkImage() 加载网络图片

    其中,asset首先需要在根目录下建立images文件夹,然后在pubspec.yaml文件中添加引用才能使用

    flutter:
      uses-material-design: true
      assets:
        - images/ic_launcher.png
    
                  Image.asset(
                    'images/ic_launcher.png',
                    width: 100,
                    height: 100,
                    fit: BoxFit.fitHeight,
                  ),
    
                  Image(
                    image: new NetworkImage(
                        'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                    width: 100,
                    height: 100,
                    fit: BoxFit.cover,
                  )
    
    image.png
    • TextField
            TextField(
                //键盘输入方式
                keyboardType: TextInputType.number,
                decoration: InputDecoration(
                  //提示文字
                  hintText: '请输入手机号',
                  //内容边距
                  contentPadding: EdgeInsets.all(10),
                  //提示文字样式
                  hintStyle:
                      TextStyle(color: Colors.deepOrangeAccent, fontSize: 18),
                  //边框
                  border: OutlineInputBorder(
                    //圆角
                    borderRadius: BorderRadius.all(Radius.circular(4)),
                    borderSide: BorderSide(color: Colors.deepOrange),
                  ),
                ),
                //文字改变时调用
                onChanged: (String content) {
                  print("content=" + content);
                },
                //光标颜色
                cursorColor: Colors.deepOrangeAccent,
                //光标圆角
                cursorRadius: Radius.circular(4),
                //光标宽度
                cursorWidth: 2,
              )
    

    布局型

    Widget 多个子Widget 介绍
    Container 默认充满,包含了padding、margin、color、宽高、decoration 等配置
    Padding 用于设置padding,对,你没有猜错,绝大部分Widget是没有padding属性的
    Center 用于居中显示
    Column 垂直布局,类似于LinearLayout 的orientation="vertical"
    Row 水平布局,类似于LinearLayout 的orientation="horizontal"
    Stack 类似于relativeLayout 或者FrameLayout
    ListView 类似于ListView或者RecyclerView
    • Container
    • Padding
    • Column
    • Row
    class ContainerDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('ContainerDemo'),
          ),
          body: Container(
            margin: EdgeInsets.all(10),
            padding: EdgeInsets.only(left: 10, right: 20),
    //        color: Colors.orangeAccent,
            decoration: new BoxDecoration(
                //设置了decoration的color,就不能设置Container的color,否则会报错
                color: Colors.white,
                borderRadius: BorderRadius.all(Radius.circular(10)),
                border: new Border.all(width: 10, color: Colors.blue)),
            child: Column(
              //Column 垂直方向,Row 水平方向
              mainAxisAlignment: MainAxisAlignment.center,
              //max相当于match_parent,min相当于wrap_content
              mainAxisSize: MainAxisSize.max,
              verticalDirection: VerticalDirection.up,
              children: <Widget>[
                Container(
                  padding: EdgeInsets.all(10),
                  margin: EdgeInsets.all(20),
                  color: Colors.black54,
                  child: Text(
                    '1111111',
                  ),
                ),
                Text(
                  '111FFFFg',
                  style: TextStyle(
                    fontSize: 18,
                    backgroundColor: Colors.black54,
                  ),
                ),
                Text('222'),
                Text('333'),
              ],
            ),
          ),
        );
      }
    }
    
    • Stack

    Stack 类似于relativeLayout 或者FrameLayout,有2种定位方式

    1.alignment 作用于是全部的子Widget

    class StackDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.white,
          child: Stack(
            textDirection: TextDirection.ltr,
            //以整个组件的中心为坐标原点,x、y 偏移量取值范围为 [-1,1],
            // 如果 x 的偏移量大于 0,则表示向右偏移,小于 0 则向左偏移;
            // 如果 y 轴的偏移量大于 0 则向下偏移,小于 0 则向上偏移。
    //        alignment: Alignment(0, 0),
            //AlignmentDirectional.topStart:垂直靠顶部水平靠左对齐
            //AlignmentDirectional.topCenter:垂直靠顶部水平居中对齐
            //AlignmentDirectional.topEnd:垂直靠顶部水平靠右对齐
            //AlignmentDirectional.centerStart:垂直居中水平靠左对齐
            //AlignmentDirectional.center:垂直和水平居中都对齐
            //AlignmentDirectional.centerEnd:垂直居中水平靠右对齐
            //AlignmentDirectional.bottomStart:垂直靠底部水平靠左对齐
            //AlignmentDirectional.bottomCenter:垂直靠底部水平居中对齐
            //AlignmentDirectional.bottomEnd:垂直靠底部水平靠右对齐
            alignment: AlignmentDirectional.centerEnd,
            children: <Widget>[
              Container(
                color: Colors.black54,
                child: Text(
                  '1111111',
                ),
              ),
              Text('111FFFFg',
                  style: TextStyle(fontSize: 18, backgroundColor: Colors.black54)),
              Text('22222222')
            ],
          ),
        );
      }
    }
    
    image.png
    2.Positioned
    只能控制单个Widget,主要有leftrighttopbottomwidthheight几个属性,分别表示距左、右、上、下的边距,长度和宽度
    注意:
    1)leftright并存时,left生效;topbottom并存时,top生效
    2)leftrightwidth不能并存,topbottomheight不能并存,会报错
    class StackDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.white,
          child: Stack(
            textDirection: TextDirection.ltr,
           children: <Widget>[
              Container(
                color: Colors.black54,
                child: Text(
                  '1111111',
                ),
              ),
              Positioned(
                top: 100,
                child: Text(
                  '111FFFFg',
                  style: TextStyle(
                    fontSize: 18,
                    backgroundColor: Colors.black54,
                  ),
                ),
              ),
              Positioned(
                child: Text('22222222'),
                right: 10,
                top: 200,
              )
            ],
          ),
        );
      }
    }
    
    image.png
    • ListView
      主要有3种构造方式
      ListView.builder
      ListView.separated
      ListView.custom

    1.ListView.builder
    使用自带的item --ListTile

    class ListViewDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('ListViewDemo'),
            centerTitle: true,
          ),
          body: Container(
            color: Colors.white,
            child: ListView.builder(
              //item
              itemBuilder: (context, index) {
                return ListTile(
                  //前置图标
                  leading: new Icon(Icons.list),
                  title: new Text('标题'),
                  subtitle: new Text('副标题'),
                  //后置图标
                  trailing: new Icon(Icons.arrow_forward_ios),
                  //内容边距
                  contentPadding: EdgeInsets.all(10),
                );
              },
              //数量
              itemCount: 10,
              //内容适配
              shrinkWrap: true,
              //内边距
              padding: EdgeInsets.only(left: 10),
              //是否倒叙
              reverse: false,
              //item 高度 让item加载更加高效
              itemExtent: 50,
    
              //滑动方式
              //AlwaysScrollableScrollPhysics() 总是可以滑动
              //NeverScrollableScrollPhysics禁止滚动
              //BouncingScrollPhysics 内容超过一屏 上拉有回弹效果
              //ClampingScrollPhysics 包裹内容 不会有回弹
              physics: BouncingScrollPhysics(),
              //预加载
              cacheExtent: 10,
            ),
          ),
        );
      }
    }
    
    image.png
    2.ListView.separated
    相当于原生中的多类型,核心是separatorBuilder,与itemBuilder是一同渲染的,可以用它来实现分割线
    ListView.separated(
              itemBuilder: (context, index) {
                return ListTile(
                  //前置图标
                  leading: new Icon(Icons.list),
                  title: new Text('标题'),
                  subtitle: new Text('副标题'),
                  //后置图标
                  trailing: new Icon(Icons.arrow_forward_ios),
                  //内容边距
                  contentPadding: EdgeInsets.all(10),
                );
              },
              separatorBuilder: (context, index) {
                return Divider(
                  color: Colors.black45,
                  height: 10,
                  //左边缩进
                  indent: 50,
                );
              },
              itemCount: 20,
            )
    
    image.png
    3.ListView.custom
    前2种方式是此方式的快捷方式,虽然不常用,但还是要了解下
            ListView.custom(
              childrenDelegate: SliverChildBuilderDelegate((context, index) {
                return ListTile(
                  //前置图标
                  leading: new Icon(Icons.list),
                  title: new Text('标题 custom'),
                  subtitle: new Text('副标题 custom'),
                  //后置图标
                  trailing: new Icon(Icons.arrow_forward_ios),
                  //内容边距
                  contentPadding: EdgeInsets.all(10),
                );
              }),
            )
    

    效果同方式1

    示例

    模拟器上间隔线显示有问题,真机正常

    image.png
    ListViewDemo相关代码
    class ListViewDemo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('ListViewDemo'),
            centerTitle: true,
          ),
          body: Container(
            color: Colors.white,
            child: ListView.separated(
              itemBuilder: ((context, index) {
                return MoveItem();
              }),
              separatorBuilder: (context, index) {
                return Divider(
                  color: Colors.black45,
                  height: 10,
                );
              },
              itemCount: 10,
            ),
          ),
        );
      }
    }
    

    MoveItem相关代码

    class MoveItem extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          margin: EdgeInsets.all(4),
          child: Row(
            children: <Widget>[
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: Image.network(
                  'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg',
                  width: 100,
                  height: 150,
                  fit: BoxFit.fill,
                ),
              ),
              Padding(
                padding: EdgeInsets.only(left: 15),
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  Text(
                    '狄仁杰之四大天王',
                    style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
                  ),
                  Text('豆瓣评分6.6'),
                  Text('类型:动作、惊悚、冒险'),
                  Text('导演:徐克'),
                  Row(
                    children: <Widget>[
                      Text('主演:'),
                      Padding(
                        padding: EdgeInsets.only(left: 10),
                      ),
                      Container(
                        width: 40,
                        height: 40,
                        child: CircleAvatar(
                          backgroundImage: NetworkImage(
                              'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                        ),
                      ),
                      Container(
                        width: 40,
                        height: 40,
                        margin: EdgeInsets.only(left: 10),
                        child: CircleAvatar(
                          backgroundImage: NetworkImage(
                              'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                        ),
                      ),
                      Container(
                        width: 40,
                        height: 40,
                        margin: EdgeInsets.only(left: 10),
                        child: CircleAvatar(
                          backgroundImage: NetworkImage(
                              'http://n.sinaimg.cn/sports/2_img/upload/cf0d0fdd/107/w1024h683/20181128/pKtl-hphsupx4744393.jpg'),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
        );
      }
    }
    

    相关文章

      网友评论

        本文标题:【Flutter】开发之基础Widget(三)

        本文链接:https://www.haomeiwen.com/subject/mvwuaqtx.html