Flutter Tips 小技巧(更新中)(上)

简介: Flutter Tips 小技巧(更新中)(上)

大佬们点波关注呀,从小家境贫寒,没见过四位数字,让我关注人数破千吧~


1.销毁和未创建调用


及时停止或者销毁监听,例如一个定时器:

Timer _countdownTimer;
  @override
  void dispose() {
    _countdownTimer?.cancel();
    _countdownTimer = null;
    super.dispose();
  }

为了保险我们还要在调用setState()前判断当前页面是否存在:

_countdownTimer = Timer.periodic(Duration(seconds: 2), (timer) {
    if (mounted){
      setState(() {
      });
    }
  });


2.先绘制再请求


addPostFrameCallback 回调方法在Widget渲染完成时触发,所以一般我们在获取页面中的 Widget 大小、位置时使用到。

解决方法就是使用 addPostFrameCallback 回调方法,等待页面 build 完成后在请求数据:

@override
void initState() {
  WidgetsBinding.instance.addPostFrameCallback((_){
    /// 接口请求
  });
}


3.保持页面状态


比如点击导航栏来回切换页面,默认情况下会丢失原页面状态,也就是每次切换都会重新初始化页面。这种情况解决方法就是 PageViewBottomNavigationBar结合使用,同时子页面 State 中继承 AutomaticKeepAliveClientMixin 并重写 wantKeepAlive 为true。代码大致如下:

class _TestState extends State<Test> with AutomaticKeepAliveClientMixin{
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Container();
  }
  @override
  bool get wantKeepAlive => true;
}


4.预先缓存图片


在 Flutter 中,加载本地图片会存在一个加载过程。比如点击图标做图标的切换时,那么首次会发生闪动的情况。尤其是做类似引导页这类需求是,通过左右滑动切换图片时会发生比较明显的白屏一闪而过。


image.png


解决方法很简单,就是使用 precacheImage,它将图像预存到图像缓存中。如果图像稍后被 Image、BoxDecation 或 FadeInImage 使用,它会被加载得更快。

precacheImage(AssetImage("assets/logo"), context);

本问题详细的代码见:点击查看


5.屏幕方向


新建的 Flutter 项目默认并没有限制屏幕的横竖屏,所以如果你的项目并没有适配横竖屏,需要限制某一方向。我以限制竖屏为例:

void main(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]).then((_){
    runApp(MyApp());
  });
}


6.FutureBuilder 懒加载


Flutter 中通过 FutureBuilder 或者 StreamBuilder 可以和简单的实现懒加载,通过 future 或者 stream “异步” 获取数据,之后通过 AsyncSnapshot 的 data 再去加载数据,至于流和异步的概念,以后再展开吧。

const FutureBuilder({
    Key key,
    this.future,//获取数据的方法
    this.initialData,
    @required this.builder//根据快照的状态,返回不同的widget
  }) : assert(builder != null),
       super(key: key);

future 就是一个定义的异步操作,注意要带上泛型,不然后面拿去 snapshot.data 的时候结果是 dynamic 的 snapshot 就是 future 这个异步操作的状态快照,根据它的 connectionState 去加载不同的 widget 有四种快照的状态:

enum ConnectionState {
   //future还未执行的快照状态
  none,
  //连接到一个异步操作,并且等待交互,一般在这种状态的时候,我们可以加载个菊花
  waiting,
  //连接到一个活跃的操作,比如stream流,会不断地返回值,并还没有结束,一般也是可以加载个菊花
  active,
  //异步操作执行结束,一般在这里可以去拿取异步操作执行的结果,并显示相应的布局
  done,
}


7.StreamBuilder 流控制管理


从一端发射一个事件,从另外一端去监听事件的变化,通过 Stream 我们可以在 Flutter 上设计出基于事件流驱动的响应式代码逻辑。常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。

class StreamDemo extends StatefulWidget {
  @override
  _StreamDemoState createState() => _StreamDemoState();
}
class _StreamDemoState extends State<StreamDemo> {
  var index = 0;
  var streamController;
  StreamSink<String> get streamSink => streamController.sink;
  Stream<String> get streamData => streamController.stream;
  @override
  void initState() {
    super.initState();
    streamController = StreamController<String>();
    streamSink.add("0");
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('streamBuilder')),
        body: StreamBuilder<String>(
          stream: streamData,
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            return Text('Result: ${snapshot.data}');
          },
        ),
        floatingActionButton: FloatingActionButton(
            onPressed: onFloatActionButtonPress, child: Icon(Icons.add)));
  }
  void onFloatActionButtonPress() {
    index++;
    streamSink.add(index.toString());
  }
}


8.Future 发起多个异步操作的方式


复杂耗时操作或者多个网络请求并对完整性要求较高的操作,可以使用 Future 异步方法:

Future.wait([
  // 2秒后返回结果  
  Future.delayed(new Duration(seconds: 2), () {
    return "hello";
  }),
  // 4秒后返回结果  
  Future.delayed(new Duration(seconds: 4), () {
    return " world";
  })
]).then((results){
  print(results[0]+results[1]);
}).catchError((e){
  print(e);
});


9.Text 上下边距调整


image.png


左侧的彩色矩形是支柱(尽管实际上支柱没有宽度)。这个矩形的高度是最小的线条高度。这条线不能再短了。但它可以更高。

  • 上升是从基线到文本顶部的距离(由字体定义,而不是任何特定的字形)
  • 下降是从基线到文本底部的距离(由字体定义,而不是任何特定的字形)

前导(读作“ledding”,如旧排字机用来排字的铅字金属)是一行底端和下一行顶端之间的距离。在支柱中,一半的引线放在顶部,一半放在底部。是图中的灰色区域。 > 可以使用乘数更改支柱的垂直尺寸。

class TextLineHeight extends StatelessWidget {
  final String textContent;
  final double leading;
  final double textLineHeight;
  final double fontSize;
  TextLineHeight({
    this.textContent,
    this.leading: 0,
    this.textLineHeight: 0.93,
    this.fontSize: 26,
  });
  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(0, fontSize/11.52),
      child: Text(
        textContent,
        strutStyle: StrutStyle(
          forceStrutHeight: true,
          height: textLineHeight,
          leading: leading,
          fontSize: fontSize,
        ),
        style: TextStyle(
          fontSize: fontSize,
          color: Colors.black,
        ),
      ),
    );
  }
}

效果对比:


image.png


10.空判断


使用 null-aware operators 判断 null,减少代码量。

// User below
title ??= "Title";
// instead of
if (title == null) {
  title = "Title";
}

上面的方法可以在只有一层判断中做保护,如果你有一连串的’.’取值,那就需要用这种方法了。

xxCount = xxModel?.xxInfo?.xxCount ?? 0


11.VSCode 配置项


{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Main",
            "type": "dart",
            "request": "launch",
            "program": "lib/main.dart”,
            "flutterMode": "profile" # 测试完后记得把它改回去!
        },
        {
            "name": "Dev",
            "type": "dart",
            "request": "launch",
            "program": "lib/main_dev.dart",
            "args": [
                "--flavor",
                "universal",
            ],
            "flutterMode": "profile" # 测试完后记得把它改回去!
        },
        {
            "name": "Prod",
            "type": "dart",
            "request": "launch",
            "program": "lib/main_prod.dart",
            "args": [
                "--flavor",
                "universal",
            ],
        },
    ]
}


目录
相关文章
|
6月前
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套 在 Flutter 中,ListView 和 PageView 是两个常用的控件,它们可以用于滑动展示大量内容的场景,且支持各种嵌套方式,本文将介绍其中的一些花式嵌套方式。
266 0
|
6月前
|
Dart 安全
简化代码、提高效率:Dart和Flutter开发小技巧
在日常开发中,我们常常会使用一些常用的技巧或语法糖,以简化代码、提高开发效率。本文将分享一些在Dart和Flutter中常用的小贴士,帮助你更轻松地编写优雅高效的代码。
简化代码、提高效率:Dart和Flutter开发小技巧
|
4月前
|
Android开发
Flutter路由跳转参数处理小技巧
Flutter路由跳转参数处理小技巧
43 0
|
4月前
Flutter生命周期方法小技巧
Flutter生命周期方法小技巧
30 0
|
安全 开发工具 git
Flutter:实战小技巧
本文主要介绍在 Flutter 开发中的一些实用技巧。
211 0
Flutter:实战小技巧
|
Dart Android开发 开发者
Flutter Tips 小技巧(更新中)(下)
Flutter Tips 小技巧(更新中)(下)
394 0
Flutter Tips 小技巧(更新中)(下)
|
移动开发 开发工具 git
Flutter Tips 小技巧(更新中)(中)
Flutter Tips 小技巧(更新中)(中)
237 0
|
Dart Android开发
flutter开发中的几个小技巧
我的tabBar有一个StatelessWidget小部件,其中包含2个statefulWidgets。事实是,当单击管理器以查看我的所有选项卡时(默认情况下在我的第一个选项卡上登陆),tab1小部件生成器一直被调用。
153 0
|
Android开发
flutter开发小技巧
flutter - URL出现在网站名称的位置 从Android Studio运行时:
163 0
|
容器
flutter开发小技巧
粘性标题效果 带有粘性标题的每个部分都应该是带有 SliverPinnedHeader 和 SliverList 的多条。然后将 pushPinnedChildren 设置为 true 应该会提供您正在寻找的粘性标题效果。
160 0