Flutter小记

作者: 91阿生 | 来源:发表于2021-01-21 11:00 被阅读0次
    0.关于AppBar中leading
    如果没有leading,automaticallyImplyLeading为true,就会默认返回箭头
    如果 没有leading 且为false,空间留给title
    如果有leading,automaticallyImplyLeading 这个参数就无效了
    
    1.关于ElevatedButton
    image.png
    ElevatedButton(
       child: Text("立即体验"),
       style: ButtonStyle(
           foregroundColor: MaterialStateProperty.all(Color(0xFF535149)),
          backgroundColor: MaterialStateProperty.all(ColorFit.mainColor),
          textStyle: MaterialStateProperty.all(TextStyle(
               fontSize: 16,
               fontWeight: FontWeight.bold
          )),
       shape: MaterialStateProperty.all(RoundedRectangleBorder(
             borderRadius: BorderRadius.circular(8)
       )),
       side: MaterialStateProperty.all(BorderSide(color: Colors.red, width: 2))),
       onPressed: () {  },
    )
    
    2.关于initState中拿不到context

    解决:

    Future.delayed(Duration.zero, () {
       // 延迟0秒,异步执行
       Navigator.of(context).pushReplacementNamed(MainPage.routeName);
    });
    
    3.关于PageView使用切换图片时,图片之间会有短暂的背景显示

    解决:

    // Implicit:含蓄的
    设置属性 allowImplicitScrolling: true
    
    4.关于取消scroller边缘弹簧效果

    解决:

    设置属性 physics: ClampingScrollPhysics()
    
    5.关于设置命名路由问题

    描述:设置命名路由时,主路由设置成 '/' 路由A,其他所注册的路由命名为 '/xxx'(非'/'),则系统会默认初始路由设置成由 '/'命名的路由A,这样在使用push替换路由(pushReplacementNamed)时,导航栏上会显示出返回按钮(如果此路由有导航栏),或左侧边缘可以拉回到主路由A页面。

    【明明在MaterialApp中设置的initialRoute:为引导页/Launch页,但系统还是会默认初始路由为 '/'的主路由。】

    解决:

    可能原因注册其他路由时,其他路由的命名都为 / 开头;
    例如像 引导页/Launch页 路由命名时,前面不用加 /  这样就正常了。
    
    建议:不是经常使用到的页面,则路由命名可以不添加 /
    
    6.关于全局消除水波纹效果,长按水波纹效果

    解决:

    theme: ThemeData(
       splashColor: Colors.transparent, // 全局设置点击水波纹颜色, 去除长按不放, 水波效果
       highlightColor: Colors.transparent // 全局去除点击的水波纹效果
    )
    
    7. TabBar() + TabBarView() + TabController配合
    TabBar:设置标题,设置指示器样式等
    TabBarView:存放标题对应的页面
    TabController:使得 TabBar 与 TabBarView进行关联
    
    选择栏.png
    7. NestedScrollView 与 CustomScrollView

    NestedScrollView:用来处理复杂情况下的滑动应用场景,如向上滑动视图时,要折叠隐藏一部分内容,这时候就需要使用到 NestedScrollView 与 SliverAppBar 的结合使用。

    CustomScrollView:用来处理更为复杂的布局,可以将SliverAppBar,SliverList和SliverGrid SliverPadding SliverToBoxAdapter SliverPersistentHeader, SliverFillRemaining,SliverFillViewport组合等来使用。

    8. 关于TextField 获取焦点 + 取消焦点
     ①、创建FocusNode实例aNode,并设置对应TextField的属性focusNode: aNode
     ②、获取焦点:FocusScope.of(context).requestFocus(aNode);
     ③、失去焦点:aNode.unfocus();
    
    9. 回收键盘操作
    SystemChannels.textInput.invokeMethod("textInput.hide");
    
    10. 关于键盘监听操作

    1、使用 with WidgetsBindingObserver 绑定监听
    2、由于键盘开启后,应用视图尺寸会改变,则会被 WidgetsBindingObserver 监听到, 就会回调走此函数
    @override
    void didChangeMetrics() {}

    @override
      void didChangeMetrics() {
        super.didChangeMetrics();
    
        // 当键盘开启后, 界面会往上, 这里绑定监听界面缩小
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
           // 获取底部被遮挡的高度
            double keybordHeight = MediaQuery.of(context).viewInsets.bottom;
            print("键盘高度: $keybordHeight");
    
            // 判断
            if (keybordHeight == 0) { // 键盘收起状态
              
            } else {
              
            }
        });
      }
    
    11. 关于去处导航栏左侧自带返回按钮
    appBar: AppBar(
       automaticallyImplyLeading: false,
    ),
    
    12. 关于dart中math函数
    int i = -1; //定义一个整型变量i
    double j = 2.1; //定义一个小数j
      print(i.abs());//求i的绝对值,打印 ‘1’
      print(j.ceil());//求j的向上最大整数,打印'3'
      print(j.floor());//求j的向下的最大整数,打印'2'
      print(j.round());//求离j最近的整数,四舍五入,打印'2'
      print(j.truncate());//截取掉小数点取整,打印'2'
      
    double j = 2.6;//验证小数位超过0.5的情形
        print(j.round());//求离j最近的整数,四舍五入,打印'3'
        print(j.truncate());//截取掉小数点取整,打印'2'
        print(j.clamp(1,3));//如果j再1-3之间则返回 j,这里打印j的值 ‘2.6’;否则返回离其最近的边界值。
        print(j.clamp(3,4));//打印‘3’,原理同上
        print(j.clamp(1,2));//打印‘2’,原理同上
    
    //保留n 位小数:  .toStringAsFixed(n)
    double j = 2.6;
    String rs = j.toStringAsFixed(2) = "2.60"; 
    
    1.toStringAsFixed(3);  // 1.000
    (4321.12345678).toStringAsFixed(3);  // 4321.123
    (4321.12345678).toStringAsFixed(5);  // 4321.12346
    123456789012345.toStringAsFixed(3);  // 123456789012345.000
    10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
    5.25.toStringAsFixed(0); // 5
    
    13. 关于flutter中List既能获取value,也能获取下角标index
    例子:final List<String> _titles = ['2021', '2020', '2019', '2018', '2017', '2016'];
    
    ...
    tabs: titles.asMap().entries.map((item) {
       return Tab(
         child: Container(
            child: Text('$(item.value) === $item.key'),
         ),
      );
    }).toList()  
    
    14. 关于flutter中拦截导航栏返回事件
    class SearchPage extends StatelessWidget {
      static const String routeName = '/search';
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            print('true:可点击返回上一个界面;false:点击返回效果被禁用');
            return false;
          },
          child: Scaffold(
            appBar: AppBar(
              title: Text(''),
            ),
            body: Center(
              child: Text(''),
            ),
          ),
        );
      }
    }
    
    15. 关于flutter中关于导航栏左侧宽度不够问题

    实现如下图:


    image.png
    AppBar(
      elevation: 1.0,
      automaticallyImplyLeading: false,
      title: Row(
         mainAxisAlignment: MainAxisAlignment.start,
         crossAxisAlignment: CrossAxisAlignment.center,
         children: <Widget>[
                Image.asset(ImageTool.loadOthersImgPath('other_back_dark')),
                Text(widget.navTitle, style: TextStyle(
                    fontSize: 14,
                    color: Colors.black
                  ),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                )
              ],
            ),
          ),
    
    16. 关于flutter中使用 shared_preferences 出现 Unhandled Exception: Null check operator used on a null value 问题
    解决:
     void main() { 
        WidgetsFlutterBinding.ensureInitialized();
     }
    
    17. 关于flutter中查询 文本中共有多少个换行,并替换换行符为空格
    /// 换行符个数:
    final numLines = '\n'.allMatches(content).length + 1;
    
    /// \n 替换成 空格" "
    String rsContent = model.content.replaceAll(RegExp(r"\n"), " ");
    
    18. 关于监听一个界面的 pop / push (WidgetsBindingObserver)
    image.png

    代码:

    /* 用于监听 每个界面的 push pop 组件出现或者消失的回调,主要是要靠路由的监听 */
    import 'package:flutter/material.dart';
    
    class AppRouteObserver {
      //这是实际上的路由监听器
      static final RouteObserver<ModalRoute<void>> _routeObserver = RouteObserver<ModalRoute<void>>();
      //这是个单例
      static AppRouteObserver get shared => AppRouteObserver();
    
      static AppRouteObserver? _instance;
      factory AppRouteObserver() {
        return _instance ??= AppRouteObserver._internal();
      }
    
      AppRouteObserver._internal() {}
     
      RouteObserver<ModalRoute<void>> get routeObserver => _routeObserver;
    }
    

    使用:

    ⑴ 
    。。。 with WidgetsBindingObserver
    
    ⑵  
      @override
        void initState() {
          WidgetsBinding.instance?.addObserver(this);
          super.initState();
        }
    
    ⑶ 
      @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        //路由订阅
        AppRouteObserver.shared.routeObserver
            .subscribe(this, ModalRoute.of(context)!);
      }
    
    ⑷ 
      @override
      void didPush() {
        //当前页面显示时
        print("哈哈didPush");
        super.didPush();
      }
    
      @override
      void didPushNext() {
        //当前页面 push 到另一个页面
        print("哈哈didPushNext");
        super.didPushNext();
      }
    
      @override
      void didPop() {
        //当前的页面被pop.
        print("哈哈didPop");
        super.didPop();
      }
    
      @override
      void didPopNext() {
        //另一个页面 pop 到当前页面时.
        print("哈哈didPopNext");
        super.didPopNext();
      }
    
    ⑸
      @override
      void dispose() {
        AppRouteObserver.shared.routeObserver.unsubscribe(this);
        WidgetsBinding.instance?.removeObserver(this);
        super.dispose();
      }
    
    

    相关文章

      网友评论

        本文标题:Flutter小记

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