Nealyang/PersonalBlog

盘一盘Flutter中“小巧”的组件与属性

Nealyang opened this issue · 0 comments

前言

不仅仅局限于 widget,可能会从widget中衍生出一些相似的 package

鉴于市面上关于 Flutter 常用widget介绍已经非常多了,这里主要介绍下那些不常用,但是也非常实用的一些widget。

原文地址:Nealyang/personalBlog

demo地址:Nealyang/flutter

Widgets && property

Opacity

Opactiy 透明度,跟css的属性非常相似,连带child也同样透明,当然,其实Opacity本身是一个widget,如果不添加child也就没有透明的意义。

Opacity控制子 Widget 的透明度,opacity 属性为必传,可以设置 0.0~1.0之间的值。

          Opacity(
            opacity: .5,
            child: Container(
              height: 30.0,
              color: Colors.blue,
              child: Center(child:Text('透明度为:0.5')),
            ),
          ),
          Opacity(
            opacity: 1.0,
            child: Container(
              height: 30.0,
              color: Colors.red,
              child: Center(child:Text('透明度为:1.0')),
            ),
          ),

img

FadeInImage

带有淡入动画的 Image 组件,placeHodler是image到目标图片的一种过渡widget。使用FadeInImage可以类似网络加载的图片以一个更加优雅的形式出现在屏幕上,如果这个图片已经被加载了,或者已经存在内存中,那么placeholder图片将不会显示。

FadeInImage的写法跟Image类似,有很多别的命名构造函数。fadeOutDuration和fadeOutCurve控制placeholder的淡出动画。fadeInDuration和fadeInCurve控制目标图像的淡入动画,对于placeholder,更倾向于使用已经缓存的,以防止他也会突然的出现在屏幕上

          FadeInImage.assetNetwork(
            placeholder: 'assets/images/tst.jpg',
            image: "https://img.alicdn.com/tfs/TB13Xh3BkvoK1RjSZFNXXcxMVXa-345-717.gif",
            width: 100.0,
            height: 200.0,
            fit: BoxFit.contain,
          ),

img

CachedNetworkImage

这个可以说是 FadeInImage 的升级版,倒是并非官方widget,而是一个package。

CachedNetworkImage 中有两个非常重要的属性:

  • placeholder 展位图。这里我们可以设置loading或者别的widget等
  • errorWidget 当网络图片加载异常的时候展示

具体的使用方法和 FadeInImage 非常的相似,这里就不做演示了,大家可以自行尝试下

WillPopScope

导航的返回监听,其中回调方法中返回一个 bool 类型的值,true 为退出页面,false则反。

    @override
    Widget build(BuildContext context) {
      return WillPopScope(
        child: Scaffold(),
        onWillPop: () async {
          if (_lastTime == null ||
              DateTime.now().difference(_lastTime) >
                  Duration(milliseconds: 2000)) {
            _lastTime = DateTime.now();
            return false;
          } else {
            return showDialog(
              context: context,
              barrierDismissible: false,
              builder: (BuildContext context){
                return AlertDialog(
                  title: Text('退出App'),
                  content: Text('别怪我没告诉你哦'),
                  actions: <Widget>[
                    FlatButton(
                      child: Text('CANCEL',),
                      onPressed: (){
                        Navigator.pop(context, false);
                      },
                    ),FlatButton(
                      child: Text('SURE',),
                      onPressed: (){
                        Navigator.pop(context, true);
                      },
                    ),
                  ],
                );
              }
            );
          }
        },
      );
    }

img

Chip

标签,类似于and中的Tag,

  • avatar 左侧图标
  • labelStyle 标签样式
  • labelPadding 标签内边距
  • deleteIcon 删除图标
  • onDeleted 删除方法,必须调用才会显示删除图标
  • deleteIconColor 删除图标颜色
  • deleteButtonTooltipMessage 删除图标的提示消息
  • shape 形状
  • backgroundColor 背景颜色
  • padding 内边距
  • materialTapTargetSize 删除图标点击范围
                Chip(
                  label: Text('标签1'),
                  padding: const EdgeInsets.symmetric(horizontal: 10.0),
                  deleteIcon: Icon(Icons.clear, color: Colors.black12),
                ),
                Chip(
                  label: Text('标签2'),
                  deleteIcon: Icon(Icons.clear, color: Colors.black12),
                  labelPadding: EdgeInsets.symmetric(horizontal: 10.0),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(3.0),
                  ),
                  onDeleted: () {
                    print(1122);
                  },
                ),
                Chip(
                  label: Text('标签3', style: new TextStyle(fontSize: 16.0)),
                  avatar: Icon(Icons.search),
                  deleteIcon: Icon(Icons.clear, color: Colors.black12),
                  labelPadding: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0),
                  onDeleted: () {},
                ),

img

Spacer

简单来说,这是一个占位的widget,当然,对于布局定位我们可以使用margin来解决。但是如果抽离出组件的话,非相关属性当然还是不能放到组件内部的,或者做成可配置的。

对于占位,我们熟知的还有SizedBox,但是 SizedBox 只能指定宽度和高度,并不能适用于我们常规使用的 Flex 布局系列。而这,正是我们介绍的 Spacer 用武之地

            Row(
              children: <Widget>[
                Text('Begin'),
                Spacer(), // Defaults to a flex of one.
                Text('Middle'),
                // Gives twice the space between Middle and End than Begin and Middle.
                Spacer(flex: 2),
                Text('End'),
              ],
            ),

img

DefaultTextStyle

统一文本样式,文档的解释是,应用于没有显示指定文本样式的子代文本组件。

当然,我们可以为App整体的文本设置基调风格,通过MaterialApp中指定textTheme属性即可。但是如若是需要统一某一个页面的文本样式, DefaultTextStyle 还是首当其选。