美文网首页
Flutter学习--flutter组件

Flutter学习--flutter组件

作者: 大良造L | 来源:发表于2020-12-14 16:38 被阅读0次

    记录个人梳理的flutter常用组件

    字体
    Text:(
    textAlign 对齐 方式
    maxLines 文本最大行数
    overflow 超出文案的截断方式
    textScaleFactor  文本字体大小缩放因子
    )
    textStyle: (
    fontWeight 加粗
    fontStyle 斜体
    letterSpacing 单词之间的间距
    wordSpacing 字母之间的间距
    decoration 文本上划线、中划线、下划线
    decorationStyle 划线样式,双划线、虚线、波浪
    )
    
    TextSpan:显示不同样式的文案
    DefaultTextStyle:设置子类文本的默认样式
    
    按钮
    RaisedButton: 凸起按钮,有背景无边框
    FlatButton:扁平按钮,无背景无边框
    OutlineButton:无背景有边框
    IconButton:带图标按钮
    RaisedButton.icon(…):带图标+文案
    
    图片
    Image.asset(…) 加载本地图片
    Image(image:AssetImage(…))  加载本地图片
    Image(image:NetworkImage(…))  加载远程图片
    width、height:只设置一个的时候另一个会按比例缩放
    fit:适应模式,填充、满铺剪切、按宽度/高度满铺等
    color:对像素进行颜色混合处理
    colorBlendMode:混合像素处理模式
    repeat:重复满铺
    Text('\uE914',style: TextStyle( fontFamily: 'MaterialIcons'),) : iconFont图标
    Icon(Icons.accessible,color: Colors.red,) :  可直接使用的iconFont图标
    
    输入框
    TextField(
        controller: 指定监听控制器
        focusNode:用于指定焦点属于哪个输入框,focusScopeNode移动焦点,focusNode.addListener可以监听焦点变化
        decoration: InputDecoration( 控制外观的显示,文本、边框、背景色等
            labelText: "用户名",
            hintText: "用户名或邮箱",
            icon: 图标
            enabledBorder:未使用下划线样式
            focusedBorder:焦点是下划线样式
             )
        keyboardType:键盘模式,数字、英文
        textInputAction:键盘回车按钮显示样式,搜索、完成等
        style:文本样式大小颜色
        textAlign:文本对齐方式
        autofocus:是否自动获得焦点
        obscureText:密码样式
        maxLines:最大行数
        maxLength:最大字数
        maxLengthEnforced:超过maxLength时,是否还能继续输入,显示红色警告
        onChange:内容改变时回调函数
        onEditingComplete:输入完成时回调,不带文本内容
        onSubmitted:输入完成时回调,带文本内容
        inputFormatters: [ 规则格式限制,字符白名单、黑名单。
                  WhitelistingTextInputFormatter(RegExp("[0-9]|[a-z]")),
                  BlacklistingTextInputFormatter(RegExp("0")),
             ],
        enable:是否禁用
        cursorWidth:光标宽度
        cursorRadius:光标圆角
        cursorColor:光标颜色
    )
    
    Form表单
    autovalidate:是否自动校验输入内容
    onWillPop:是否可以直接返回
    TextFormField:输入框
    Form.of(context).validate() :是否都效验通过
    
    进度条
    LinearProgressIndicator( 线条进度条
        value: 0.5, 当前进度
        backgroundColor: 背景色
        valueColor: AlwaysStoppedAnimation(线条颜色),
    )
    
    SizedBox(  圆形进度条
        width: 50,height: 50,
         child: CircularProgressIndicator(
            backgroundColor: Colors.grey[100],
            valueColor: AlwaysStoppedAnimation(Colors.blue),
            strokeWidth: 3, 厚度
        ),
    ),
    
    线性布局:
    Row,column(
        textDirection:子组件的布局顺序,左-右
        mainAxisSize:水平方向的占用空间,MainAxisSize.min相当于Fit
        mainAxisAlignment:水平对齐方式
        verticalDirection:另一轴对齐方向, column则是水平
        crossAxisAlignment:verticalDirection值为VerticalDirection.down时crossAxisAlignment.start指顶部对齐,verticalDirection值为VerticalDirection.up时,crossAxisAlignment.start指底部对齐
    )
    
    MainAxisAlignment {
      start,
      end,
      center,
      spaceBetween,
      spaceAround,
      spaceEvenly,
    }
    
    弹性布局:
    Expanded(  按1:2的比例布局
           flex: 1,
    ),
    Expanded(
           flex: 2,
    ),
    
    流式布局
    Wrap({
      ...
      this.direction = Axis.horizontal,     主轴方向
      this.alignment = WrapAlignment.start,     主轴对齐方式
      this.spacing = 0.0,        主轴方向子widget的间距
      this.runAlignment = WrapAlignment.start,   纵轴方向的对齐方式
      this.runSpacing = 0.0,   纵轴方向的间距
      this.textDirection,       子组件的布局顺序,左-右
      this.verticalDirection = VerticalDirection.down, 
      this.crossAxisAlignment = WrapCrossAlignment.start,    
      List<Widget> children = const <Widget>[],
    })
    
    Flow 主要用于一些需要自定义布局策略或性能要求较高(如动画中)的场景,一般情况能用wrap先用wrap
    需要自己实现FlowDelegate的paintChildren()
    
    Stack
    Stack {
        alignment : 指的是子Widget的对其方式,默认情况是以左上角为开始点,此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子组件
        fit :  用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 多大就多大,StackFit.expand使子Widget的大小和父组件一样大
        overflow :指子Widget 超出Stack时候如何显示,默认值是Overflow.clip,子Widget超出Stack会被截断,
    }
    
    Positioned({  相对于父视图的绝对位置
      this.left, 
      this.top,
      this.right,
      this.bottom,
      this.width,
      this.height,
    })
    
    Align
    Align {
        alignment : 子组件在父组件中的起始位置
        widthFactor: 2.0 缩放因子,组件本身的宽度,乘以子元素的宽。
        heightFactor:1.5 同上
    }
    
    Alignment:矩形的中心点作为坐标原点,x、y的值从-1到1分别代表矩形左边到右边的距离和顶部到底边的距离。
    公式:(Alignment.x*childWidth/2+childWidth/2, Alignment.y*childHeight+childHeight/2)
    
    FractionalOffset:继承自 Alignment,它和 Alignment是以左上角为原点
    
    容器组件
    Padding:{
        padding: EdgeInsets.all(16.0),   所有方向,  
        EdgeInsets.only(left: 8.0), 某一个方向,      
        EdgeInsets.symmetric(vertical: 8.0) 轴方向,    
        EdgeInsets.fromLTRB(20.0,.0,20.0,20.0), 上下左右
    }
    
    ConstrainedBox:{  用于对子组件添加额外的约束,如果有多重时候取最大值
        constraints: BoxConstraints({
             this.minWidth = 0.0, //最小宽度
             this.maxWidth = double.infinity, //最大宽度
             this.minHeight = 0.0, //最小高度
             this.maxHeight = double.infinity //最大高度
        })
        BoxConstraints.expand() 生成一个尽可能大的容器
        BoxConstraints.tight(Size size),它可以生成给定大小的限制;
    }
    UnconstrainedBox: 父级的约束不限制子元素
    
    SizedBox:{ 用于给子元素固定宽高
        width:
        height: 
        等价于 BoxConstraints.tightFor(width: ,height:),
    }
    
    FittedBox:{  会在自己的尺寸范围内缩放并且调整child位置,使得child适合其尺寸
        fit: BoxFit.contain, fill 等
            alignment: Alignment.topLeft,
    }
    
    AspectRatio:{ 调整child到设置的宽高比 
        aspectRatio: 1.5 宽高比w:h
    }
    
    LimitedBox:{ 限制最大宽高的控件
        maxWidth:
        maxHeight:
    }
    
    FractionallySizedBox:{ 根据父容器宽高的百分比来设置子组件宽高
        alignment: Alignment.topLeft,
            widthFactor: 1.5,  是父容器的1.5倍宽
            heightFactor: 0.5,  是父容器的0.5倍高
    }
    
    DecoratedBox:可以在其子组件绘制前或后绘制一些装饰(Decoration),如背景、边框、渐变等
    BoxDecoration:{ 是DecoratedBox的子类
        Color color, //颜色
        DecorationImage image,//图片
        BoxBorder border, //边框
         BorderRadiusGeometry borderRadius, //圆角
        List<BoxShadow> boxShadow, //阴影,可以指定多个
        Gradient gradient, //渐变
        BlendMode backgroundBlendMode, //背景混合模式
        BoxShape shape = BoxShape.rectangle, //形状
    }
    
    Transform: { 矩阵变换
        alignment: Alignment.topRight,  //相对于坐标系原点的对齐方式
        transform: new Matrix4.skewY(0.3),  //沿Y轴倾斜0.3弧度
    }
    Transform的变换是应用在绘制阶段,而并不是应用在布局(layout)阶段,所以无论对子组件应用何种变化,其占用空间的大小和在屏幕上的位置都是固定不变的,因为这些是在布局阶段就确定的
    
    Transform.translate(  平移
          offset: Offset(-10, 15),
           child: Text('平移'),
    )
    
    Transform.scale( 缩放
        scale: 2,  子元素缩放因子
        child: Text('缩放'),
    )
    
    Transform.rotate( 旋转
        angle: math.pi/2,
        child: Text('这是一个旋转'),
    )
    先平移在旋转,和先旋转再平移是不一样的, 轴会发送变换,除非旋转360°
    
    RotatedBox:{ Transform.rotate功能相似,它们都可以对子组件进行旋转变换,但是有一点不同:RotatedBox的变换是在layout阶段,会影响在子组件的位置和大小
        quarterTurns:1  // 旋转 1/4圈
        child:
    }
    
    Container({
      this.alignment,
      this.padding, //容器内边距
      this.margin,//容器外边距
      Color color, // 背景色
      Decoration decoration, // 背景装饰
      Decoration foregroundDecoration, //前景装饰
      double width,//容器的宽度
      double height, //容器的高度
      BoxConstraints constraints, //容器大小的限制条件
      this.transform, //变换
      this.child,
    })
    
    AppBar
    AppBar({
      this.leading, //导航栏最左侧Widget,常见为抽屉菜单按钮或返回按钮。
      this.automaticallyImplyLeading = true, //如果leading为null,是否自动实现默认的leading按钮
      this.title,// 页面标题
      this.actions, // 导航栏右侧菜单
      this.bottom, // 导航栏底部菜单,通常为Tab按钮组
      this.elevation = 4.0, // 导航栏阴影
      this.centerTitle, //标题是否居中 
      this.backgroundColor,
    })
    
    TabBar
    TabBar(   //生成Tab菜单
        controller: _tabController,
            tabs: tabs.map((e) => Tab(text: e)).toList()
        isScrollable, 是否可以水平滑动
        labelStyle,文字样式
        labelColor,选中样式
        unselectedLabelColor,未选中样式
        indicatorColor,指示条颜色,
        indicatorWight,指示条厚度
        indicator,指示器
     ),
    
    Tab({
            this.text,
            this.icon,
            this.child,
      }) 
    
    TabBarView({
        this.children,
        this.controller,
        this.physics,
        this.dragStartBehavior = DragStartBehavior.start,
      })
    
    Drawer(  抽屉
        child,
    )
    
    BottomAppBar ,底部tab
    一、
    Scaffold(
          floatingActionButton: FloatingActionButton(
            child: IconButton(icon: Icon(Icons.add),onPressed: (){print('1');},),
            onPressed: (){print('2');},
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
         bottomNavigationBar: BottomAppBar( // 底部tab
            color: Colors.white, // 背景色
            shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞
            child: Row(
              children: <Widget>[
                IconButton(icon: Icon(Icons.home),onPressed: (){},),
                SizedBox(),
                IconButton(icon: Icon(Icons.business),onPressed: (){},)
              ],
              mainAxisAlignment: MainAxisAlignment.spaceAround,
            ),
          ),
        );
    
    二、
    bottomNavigationBar: BottomNavigationBar( // 底部导航
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
              BottomNavigationBarItem(icon: Icon(Icons.business), title: Text('Business')),
              BottomNavigationBarItem(icon: Icon(Icons.school), title: Text('School')),
            ],
            currentIndex: _selectedIndex,
            fixedColor: Colors.blue,
            onTap: _onItemTapped,
          ),
    
    Clip剪切

    Clip剪切, 剪裁是在layout完成后的绘制阶段进行的,所以不会影响组件的大小,这和Transform原理是相似的

    ClipOval(child: widget),  // 剪裁为圆形或者椭圆形
    ClipRRect(  // 剪裁为圆角矩形
                borderRadius: BorderRadius.circular(5.0),
                child: avatar,
              ),
    
    CustomClipper 自定义剪切的类,如:
    class MyClipper extends CustomClipper<Rect> {
      @override
      Rect getClip(Size size) => Rect.fromLTWH(10.0, 15.0, 40.0, 30.0); 
    
      @override
      bool shouldReclip(CustomClipper<Rect> oldClipper) => false;
    }
    
    可滚动组件
    Scrollable({
      this.axisDirection = AxisDirection.down,  滚动方向
      this.controller,  监听控制器,默认有个PrimaryScrollController
      this.physics, 物理现象,如边界处iOS弹性、安卓微光
      this.viewportBuilder,  
    })
    
    Scrollbar
    Scrollbar是一个Material风格的滚动指示器(滚动条),如果要给可滚动组件添加滚动条,只需将Scrollbar作为可滚动组件的任意一个父级组件即可
    
    CupertinoScrollbar
    CupertinoScrollbar是iOS风格的滚动条,如果你使用的是Scrollbar,那么在iOS平台它会自动切换为CupertinoScrollbar
    
    ViewPort视口
    如无特别说明,则是指一个Widget的实际显示区域。例如,一个ListView的显示区域高度是800像素,虽然其列表项总高度可能远远超过800像素,但是其ViewPort仍然是800像素。
    
    SingleChildScrollView 期望的内容不会超过屏幕太多时使用,因为不支持基于Sliver的延迟实例化模型
    SingleChildScrollView({
      this.scrollDirection = Axis.vertical, //滚动方向,默认是垂直方向
      this.reverse = false,   初始滚动位置在头,true为尾
      this.padding, 
      bool primary,  //  是否使用widget树中默认的PrimaryScrollController
      this.physics,   物理现象,如边界处iOS弹性、安卓微光
      this.controller,
      this.child,
    })
    
    ListView
    ListView({
      Axis scrollDirection = Axis.vertical,   滚动方向
      bool reverse = false,    初始滚动位置在头,true为尾
      ScrollController controller,  
      bool primary,    //  是否使用widget树中默认的PrimaryScrollController
      ScrollPhysics physics,     物理现象,如边界处iOS弹性、安卓微光
      EdgeInsetsGeometry padding,
    
      double itemExtent,  //  item的高度或者宽度
      bool shrinkWrap = false,   // 是否根据子组件的总长度来设置ListView的长度
      bool addAutomaticKeepAlives = true,
      bool addRepaintBoundaries = true,
      double cacheExtent,
    
      List<Widget> children = const <Widget>[],
    })
    
    
    ListView.builder(
        itemCount: 100,   数量
        itemExtent: 50.0, // 高度
        itemBuilder: (BuildContext context, int index) {
          return ListTile(title: Text("$index")); 
        }
    );
    
    ListView.separated(
            itemCount: 100,
            itemBuilder: (BuildContext context, int index) {
              return ListTile(title: Text("$index"));
            },
            // 横线
            separatorBuilder: (BuildContext context, int index) {
              return index%2==0?divider1:divider2;
            },
        );
    
    
    Divider({  分割条
        this.height = 16.0,
        this.indent = 0.0,
        this.endIndent = 0.0,
        this.color,
      }
    
    GridView
    GridView.count(   按个数平分布局
        crossAxisCount: 3,  //  横轴方向的元素个数
        childAspectRatio: 2.0,  // 元素宽高比
        crossAxisSpacing: 50,  // 主轴(竖)方向的间距
        mainAxisSpacing: 10,  // 横轴方向的间距
        children: 
    ),
    
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                childAspectRatio: 1.0 
    ),
    
    GridView.extent(  按最大宽度布局
        maxCrossAxisExtent: 100, // 横轴方向元素的最大宽度
        crossAxisSpacing: 10,  // 横轴方向元素的间距
        mainAxisSpacing: 20, // 主轴方向元素的间距
        childAspectRatio: 2.0, // 元素宽高比
        children:
    ),
    
    gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
          maxCrossAxisExtent: 120.0,
          childAspectRatio: 2.0 //宽高比为2
      ),
    
    
    GridView.builder(  动态布局
        gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 50,
            childAspectRatio: 2,
        ),
        itemCount: _icon.length,
        itemBuilder: (BuildContext context, int index){
            return _icon[index];
        },
    ),
    
    Slivers大家族
    CustomScrollView  自定义滚动(
    scrollDirection     方向,默认Axis.vertical(垂直滚动)
    reverse         数据方向,默认false(正序)
    controller          控制器
    primary         是否使用widget树中默认的PrimaryScrollController
    physics         物理现象,如边界处iOS弹性、安卓微光
    shrinkWrap      默认false
    anchor          默认0.0
    cacheExtent  
    slivers const <Widget>[]    类型 SliverList
    semanticChildCount   
    dragStartBehavior   默认DragStartBehavior.start
    )
    
    SliverAppBar
    SliverAppBar (
    leading     头部组件(无法使用网络图片)
    automaticallyImplyLeading   默认true
    title           标题
    actions     在标题之后显示的组件
    flexibleSpace   应用栏灵活空间
    title:      标题
    background:背景
    centerTitle:    标题居中
    titlePadding:标题内边距
    collapseMode:样式
    bottom      标题下方显示的组件
    elevation       阴影高度
    forceElevated   展开状态是否显示阴影默认false
    backgroundColor 背景颜色  默认为主题颜色
    brightness  应用栏亮度。通常这是与backgroundColor, iconTheme, textTheme一起设置的
    iconTheme   应用栏图标的颜色、不透明度和大小。通常这是与背景颜色,亮度,textTheme一起设置的
    actionsIconTheme    actions样式
    textTheme   文字样式
    primary     是否为主应用栏(最顶部的应用栏)默认true
    centerTitle 标题居中
    titleSpacing    标题间距,默认NavigationToolbar.kMiddleSpacing
    expandedHeight  应用栏完全展开的高度
    floating        列表往下滑动时,是先滑header还是先滑list, false默认是先滑list
    pinned      是否固定在顶部,  true是固定,默认false
    snap     
    shape       形状
    )
    
    SliverList
    SliverList(  普通列表,不要求子元素具有相同属性
        delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index){
                return Container(
                    height:   // item高度
                ),
            },
            childCount: 4   //  item 数量
        ),
    ),
    
    SliverFixedExtentList
    SliverFixedExtentList( 具有相同高度的列表,比SliverList更高效
        itemExtent: 50,  // item 高度
        delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index){
                            return new Container();
            },
            childCount: 50,  // 数量
        ),
    ),
    
    
    SliverPrototypeExtentList( 将其子项排列在沿着主轴的一条线上,从零偏移开始,没有间隙。每个子项的约束程度与沿主轴的prototypeItem和沿横轴的SliverConstraints.crossAxisExtent的程度相同。 <不理解>
    (
        prototypeItem: SizedBox(width: 300, height: 20,),
        delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index){
                return new Container(
                    alignment: Alignment.center,
                            color: Colors.red[100],
                            child: Text('list $index'),
                            );
                     }
         ),
    ),
    
    SliverGrid
    SliverGrid(  网格列表
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
                    mainAxisSpacing: 10,
                    crossAxisSpacing: 10,
                    childAspectRatio: 4,
        ),
        delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index){
                return new Container();
            },
        childCount: 6
        )
    )
    
    SliverPadding( 给内部sliver添加间距
        padding,
        sliver,
     )
    
    SliverPersistentHeader    header分区,可自定义
    (
        pinned: true,
        floating: false,
        delegate: _SliverAppBarDelegate(
            minHeight: 40,
                    maxHeight: 40,
                    child: Container(
                            alignment: Alignment.center,
                            color: Colors.blue[100],
                            child: Text('Header_One', style: TextStyle(backgroundColor: Colors.blue[100]),),
            ),
        ),
    ),
    
    class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
      _SliverAppBarDelegate({
        @required this.minHeight,
        @required this.maxHeight,
        @required this.child,
      });
    
      final double minHeight;
      final double maxHeight;
      final Widget child;
    
      @override
      double get minExtent => minHeight;
    
      @override
      double get maxExtent => math.max(maxHeight, minHeight);
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return new SizedBox.expand(child: child);
      }
    
      @override
      bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
        return maxHeight != oldDelegate.maxHeight ||
            minHeight != oldDelegate.minHeight ||
            child != oldDelegate.child;
      }
    }
    
    SliverAppBar
    SliverAppBar(  导航栏
        title: Text('CustomScrollView'),
        expandedHeight: 200,
        floating: false, // 列表往下滑动时,是先滑header还是先滑list, false默认是先滑list
        pinned: true, // headerBar是否固定,false会跟随滑出屏幕
        snap: false,
        flexibleSpace: FlexibleSpaceBar(
            background: Image.network(url, fit: BoxFit.fill,),
        ),
    ),
    
     SliverToBoxAdapter(  把非sliver控件包裹起来放入CustomScrollview里面的时候 
        child: TextField(),
    ),
    
     SliverSafeArea(  使用SafeArea能很好的解决刘海,不规则屏幕的显示问题
        sliver: SliverPadding(
        padding: EdgeInsets.all(8.0),
        sliver: SliverListDemo(), //List
        ),
    )
    
    SliverFillRemaining(  这个部件一般用于最后填充用的,会占有一个屏幕的高度,滑动剩余部分展示的布局,如无结果
        child: Center(child: Text('FillRemaining', style: TextStyle(fontSize: 30.0))),
    ),
    
    SliverFillViewport  当item占满一屏或者比一屏更多的布局
    (
        delegate:new SliverChildBuilderDelegate(
            (BuildContext context, int index) {
                return new Container(
                    alignment: Alignment.center,
                    color: Colors.lightBlue,
                    child: new Text('SliverFillViewport'),
                );
            }, childCount: 1
        ),
        viewportFraction:1.0, //占屏幕的比例
    ),
    
    NestedScrollView({  NestedScrollView 与 ScrollView 的区别就在于 NestedScrollView 支持 嵌套滑动,无论是作为父控件还是子控件,嵌套滑动都支持,且默认开启。
        this.controller,
        this.scrollDirection = Axis.vertical,
        this.reverse = false,
        this.physics,
        @required this.headerSliverBuilder,     // header 
        @required this.body,                // body
        this.dragStartBehavior = DragStartBehavior.start,
    })
    (一般用一个SliverOverlapAbsorber包裹了SliverAppbar,在下面body里面,每一个list的上面都加了个SliverOverlapInjector。实际效果就是SliverOverlapInjector的高度就等于SliverAppbar的Pinned的高度。)
    
    ScrollController
    ScrollController
    * offset:可滚动组件当前的滚动位置。
    * jumpTo(double offset)、
    * animateTo(double offset,...):这两个方法用于跳转到指定的位置,它们不同之处在于,后者在跳转时会执行一个动画,而前者不会。
    
    WillPopScope
    WillPopScope({  返回按钮拦截
      ...
      @required WillPopCallback onWillPop,
      @required Widget child
    })
    
    InheritedWidget
    InheritedWidget 用于在树中传递信息
    1、InheritedWidget 的实现是对象池,所有InheritedWidget对象的实例都在这个对象池里,
    可以在树的任何位置都拿到InheritedWidget的单例对象,所以可以做到在树中间传递消息。
    2、在InheritedWidget中是一个数组Map<Type, InheritedElement> _inheritedWidgets;
    3、InheritedWidget的作用域只能包括自己和自己的子节点 所以InheritedWidget的传递消息 只能往下传递。
    4、InheritedWidget的在widget树中数据传递方向是从上到下的
    
    
    共享数据InheritedWidget构造
    class ShareDataWidget extends InheritedWidget {
      ShareDataWidget({
        @required this.data,
        Widget child
      }) :super(child: child);
    
      final int data; //需要在子树中共享的数据,保存点击次数
    
      //定义一个便捷方法,方便子树中的widget获取共享数据  
      static ShareDataWidget of(BuildContext context) {
        return context.inheritFromWidgetOfExactType(ShareDataWidget);
      }
    
      //该回调决定当data发生变化时,是否通知子树中依赖data的Widget  
      @override
      bool updateShouldNotify(ShareDataWidget old) {
        //如果返回true,则子树中依赖(build函数中有调用)本widget
        //的子widget的`state.didChangeDependencies`会被调用
        return old.data != data;
      }
    }
    
    
    创建向下传递数据的 widget
    child: ShareDataWidget( //使用ShareDataWidget
            data: count,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(bottom: 20.0),
                  child: _TestWidget(),//子widget中依赖ShareDataWidget
                ),
                RaisedButton(
                  child: Text("Increment"),
                  //每点击一次,将count自增,然后重新build,ShareDataWidget的data将被更新  
                  onPressed: () => setState(() => ++count),
                )
              ],
            ),
          ),
    
    
    需要使用数据的widget
    class __TestWidgetState extends State<_TestWidget> {
      @override
      Widget build(BuildContext context) {
        //使用InheritedWidget中的共享数据
        return Text(ShareDataWidget
            .of(context)
            .data
            .toString());
      }
    }
    

    #######Color

    Color  颜色
    Color(0xffdc380d); //如果颜色固定可以直接使用整数值
    color.computeLuminance() color的亮度
    
    FutureBuilder
    FutureBuilder  异步更新UI
    FutureBuilder({
      this.future,      // FutureBuilder依赖的Future,通常是一个异步耗时任务。
      this.initialData,     // 初始数据,用户设置默认数据。
      @required this.builder,   // :Widget构建器;该构建器会在Future执行的不同阶段被多次调用  
    })
    

    相关文章

      网友评论

          本文标题:Flutter学习--flutter组件

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