zoukankan      html  css  js  c++  java
  • flutter组件总结

    1、监听事件:以 Listener包裹组件支持的监听包含: onPointerDown,onPointerMove,onPointerUp,onPointerCancel。

          同 Listener 类似,有 IgnorePointer(忽略本身),和AbsorbPointer(不忽略本身)。 忽略事件。

          更强大的手势组件 GestureDetector (onTap) , 如果需要有波纹效果则用 InkWell代替,具有类似效果的还有RaisedBuitton、FlatButton、CupertinoButton。

    2、

    InkWell(波纹显示按压效果组件同GestureDetector)   必须以Material 组件为祖先,点击(出现波纹)组件.

    double sideLength = 50;
    
    Widget build(BuildContext context) {
      return AnimatedContainer(
        height: sideLength,
         sideLength,
        duration: Duration(seconds: 2),
        curve: Curves.easeIn,
        child: Material(
          color: Colors.yellow,
          child: InkWell(
            onTap: () {
              setState(() {
                sideLength == 50 ? sideLength = 100 : sideLength = 50;
              });
            },
          ),
        ),
      );
    }

    3、column和row 不支持滚动,如果要滚动请选用ListView ,复杂列表滚动效果:GridView和CustomScrollView(多列竖向滚动)。

         row 撑破横向的情况下,可以用wrap代替row

    4、InheritedWidget  父节点

    5、runZoned 代码执行环节范围,自定义一些代码行为,比如拦截日志输出行为等。

    下面是拦截应用中所有调用print输出日志的行为

    main() {
      runZoned(() => runApp(MyApp()), zoneSpecification: new ZoneSpecification(
          print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
            parent.print(zone, "Intercepted: $line");
          }),
      );
    }

    异常捕获

    runZoned(() {
        runApp(MyApp());
    }, onError: (Object obj, StackTrace stack) {
        var details=makeDetails(obj,stack);
        reportError(details);
    });

    需要注意的是,error-zone内部发生的错误是不会跨越当前error-zone的边界的,如果想跨越error-zone边界去捕获异常,可以通过共同的“源”zone来捕获,如

    var future = new Future.value(499);
    runZoned(() {
        var future2 = future.then((_) { throw "error in first error-zone"; });
        runZoned(() {
            var future3 = future2.catchError((e) { print("Never reached!"); });
        }, onError: (e) { print("unused error handler"); });
    }, onError: (e) { print("catches error of first error-zone."); });

    6、组件之间状态管理

    • 如果状态是用户数据,如复选框的选中状态、滑块的位置,则该状态最好由父Widget管理。
    • 如果状态是有关界面外观效果的,例如颜色、动画,那么状态最好由Widget本身来管理。
    • 如果某一个状态是不同Widget共享的则最好由它们共同的父Widget管理。

      下边是回调通知父组件的方法:   ValueChanged是  值改变(方法)类型

    // ParentWidget 为 TapboxB 管理状态.
    
    //------------------------ ParentWidget --------------------------------
    
    class ParentWidget extends StatefulWidget {
      @override
      _ParentWidgetState createState() => new _ParentWidgetState();
    }
    
    class _ParentWidgetState extends State<ParentWidget> {
      bool _active = false;
    
      void _handleTapboxChanged(bool newValue) {
        setState(() {
          _active = newValue;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Container(
          child: new TapboxB(
            active: _active,
            onChanged: _handleTapboxChanged,
          ),
        );
      }
    }
    
    //------------------------- TapboxB ----------------------------------
    
    class TapboxB extends StatelessWidget {
      TapboxB({Key key, this.active: false, @required this.onChanged})
          : super(key: key);
    
      final bool active;
      final ValueChanged<bool> onChanged;
    
      void _handleTap() {
        onChanged(!active);
      }
    
      Widget build(BuildContext context) {
        return new GestureDetector(
          onTap: _handleTap,
          child: new Container(
            child: new Center(
              child: new Text(
                active ? 'Active' : 'Inactive',
                style: new TextStyle(fontSize: 32.0, color: Colors.white),
              ),
            ),
             200.0,
            height: 200.0,
            decoration: new BoxDecoration(
              color: active ? Colors.lightGreen[700] : Colors.grey[600],
            ),
          ),
        );
      }
    }

      

      混合状态管理 (父子都为StatefulWidget)

    //---------------------------- ParentWidget ----------------------------
    
    class ParentWidgetC extends StatefulWidget {
      @override
      _ParentWidgetCState createState() => new _ParentWidgetCState();
    }
    
    class _ParentWidgetCState extends State<ParentWidgetC> {
      bool _active = false;
    
      void _handleTapboxChanged(bool newValue) {
        setState(() {
          _active = newValue;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Container(
          child: new TapboxC(
            active: _active,
            onChanged: _handleTapboxChanged,
          ),
        );
      }
    }
    
    //----------------------------- TapboxC ------------------------------
    
    class TapboxC extends StatefulWidget {
      TapboxC({Key key, this.active: false, @required this.onChanged})
          : super(key: key);
    
      final bool active;
      final ValueChanged<bool> onChanged;
    
      @override
      _TapboxCState createState() => new _TapboxCState();
    }
    
    class _TapboxCState extends State<TapboxC> {
      bool _highlight = false;
    
      void _handleTapDown(TapDownDetails details) {
        setState(() {
          _highlight = true;
        });
      }
    
      void _handleTapUp(TapUpDetails details) {
        setState(() {
          _highlight = false;
        });
      }
    
      void _handleTapCancel() {
        setState(() {
          _highlight = false;
        });
      }
    
      void _handleTap() {
        widget.onChanged(!widget.active);
      }
    
      @override
      Widget build(BuildContext context) {
        // 在按下时添加绿色边框,当抬起时,取消高亮  
        return new GestureDetector(
          onTapDown: _handleTapDown, // 处理按下事件
          onTapUp: _handleTapUp, // 处理抬起事件
          onTap: _handleTap,
          onTapCancel: _handleTapCancel,
          child: new Container(
            child: new Center(
              child: new Text(widget.active ? 'Active' : 'Inactive',
                  style: new TextStyle(fontSize: 32.0, color: Colors.white)),
            ),
             200.0,
            height: 200.0,
            decoration: new BoxDecoration(
              color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
              border: _highlight
                  ? new Border.all(
                      color: Colors.teal[700],
                       10.0,
                    )
                  : null,
            ),
          ),
        );
      }
    }

     7、Text 与 TextSpan

      Text的所有文本内容只能按同一种样式,如果我们需要对一个Text内容的不同部分按照不同的样式显示,这时就可以使用TextSpan,它代表文本的一个“片段”。

          children是一个TextSpan的数组,也就是说TextSpan可以包括其他TextSpan。而recognizer用于对该文本片段上用于手势进行识别处理。

    Text.rich(TextSpan(
        children: [
         TextSpan(
           text: "Home: "
         ),
         TextSpan(
           text: "https://flutterchina.club",
           style: TextStyle(
             color: Colors.blue
           ),  
           recognizer: _tapRecognizer
         ),
        ]
    ))

      DefaultTextStyle   

      如果在Widget树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式

    DefaultTextStyle(
      //1.设置文本默认样式  
      style: TextStyle(
        color:Colors.red,
        fontSize: 20.0,
      ),
      textAlign: TextAlign.start,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text("hello world"),
          Text("I am Jack"),
          Text("I am Jack",
            style: TextStyle(
              inherit: false, //2.不继承默认样式
              color: Colors.grey
            ),
          ),
        ],
      ),
    );

     要使用Package中定义的字体,必须提供package参数。例如,假设上面的字体声明位于my_package包中。然后创建TextStyle的过程如下:

    const textStyle = const TextStyle(
      fontFamily: 'Raleway',
      package: 'my_package', //指定包名
    );

    8、使用自定义字体图标

    我们也可以使用自定义字体图标。iconfont.cn上有很多字体图标素材,我们可以选择自己需要的图标打包下载后,会生成一些不同格式的字体文件,在Flutter中,我们使用ttf格式即可。

    假设我们项目中需要使用一个书籍图标和微信图标,我们打包下载后导入:

    1. 导入字体图标文件;这一步和导入字体文件相同,假设我们的字体图标文件保存在项目根目录下,路径为"fonts/iconfont.ttf":

    fonts:
      - family: myIcon  #指定一个字体名
        fonts:
          - asset: fonts/iconfont.ttf

      2、为了使用方便,我们定义一个MyIcons类,功能和Icons类一样:将字体文件中的所有图标都定义成静态变量:

    class MyIcons{
      // book 图标
      static const IconData book = const IconData(
          0xe614, 
          fontFamily: 'myIcon', 
          matchTextDirection: true
      );
      // 微信图标
      static const IconData wechat = const IconData(
          0xec7d,  
          fontFamily: 'myIcon', 
          matchTextDirection: true
      );
    }

           3、使用

    Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Icon(MyIcons.book,color: Colors.purple,),
        Icon(MyIcons.wechat,color: Colors.green,),
      ],
    )

     9、Container 相当于div,可设置margin,padding。

     10、 防止图片溢出 设置Expanded约束

    Expanded(
    child: Image.network(''),
    ),
       
    11、装饰器设置 border,背景
    decoration: BoxDecoration(
    color: Colors.white,
    border: Border(
    left: BorderSide( 0.5,color: Colors.grey);
    )
    ),
    12、装饰器设置 border,背景
    decoration: BoxDecoration(
            color: Colors.white,
            border: Border(
              bottom: BorderSide( 0.5,color: Colors.black12);
            )
          ),
     
    
    
  • 相关阅读:
    查询对象模式(下)
    淘宝code
    C#中使用消息队列RabbitMQ
    MVC5模板部署到mono
    ventBroker简单实现
    http协议知识整理(转)
    创业者应该有的5个正常心态(转)
    观点:独立游戏开发者创业路上的11个‘坑’(转)
    应用程序框架实战三十四:数据传输对象(DTO)介绍及各类型实体比较(转)
    【技巧篇】解决悬浮的<header>、<footer>遮挡内容的处理技巧(转)
  • 原文地址:https://www.cnblogs.com/Mvloveyouforever/p/12496758.html
Copyright © 2011-2022 走看看