熟读唐诗三百首,不会作诗也会吟。——孙洙

最近用Flutter开发的项目算是完成了开发到上线第一阶段了。任何一个项目开始了,若想追求的是更好,那么就需要下功夫对项目用户体验和代码效率深入的研究了。作为用户和产品经理、老板、UI、不懂技术的其他人员看到的产品只是表面的。

Flutter开发了一套代码同时运行在IOS和安卓两端那仅仅只是界面,你考虑page生命周期了吗???

做过原生的同学都知道,考虑activity生命周期,合理使用activity每个函数来发挥它的作用,有助于我们开发出高性能的app。

我们在进行原生开发的时候,activity显示时会执行onResume();当activity被遮挡或者在后台的时候会立即执行到onPause()函数。同理:我们在Flutter开发过程中,希望能像原生一样能有onResume()和onPause()这样的函数提供给我们使用,可惜没有,难道需要自定义吗???确实如此呀!!!

Flutter 简单实现BaseWidget 创建的两个page,从HomePage导航到NextPage,生命周期的提示:

I/flutter ( ......): BaseWidgetState__NextPageWidgetState_initState
I/flutter ( ......): BaseWidgetState__NextPageWidgetState_didChangeDependencies
I/flutter ( ......): BaseWidgetState__NextPageWidgetState_build
I/flutter ( ......): BaseWidgetState__HomePageWidgetState_deactivate
I/flutter ( ......): BaseWidgetState__HomePageWidgetState_build

当NextPage关闭和HomePage再一次显示时:

I/flutter ( 7347): BaseWidgetState__HomePageWidgetState_deactivate
I/flutter ( 7347): BaseWidgetState__HomePageWidgetState_build
I/flutter ( 7347): BaseWidgetState__NextPageWidgetState_deactivate
I/flutter ( 7347): BaseWidgetState__NextPageWidgetState_dispose

不难发现执行次数最多的就数deactivate()和build()函数了,灵机一动,是否可以以此内推将这两个函数作为类似原生activity生命周期onResume()和onPause(),是否真的可以呢???

是选build()???还是选deactivate()函数???来达到onResume()和onPause()的效果。

思路:

当我们确定了大致方向之后就开始着手行动了。

1、为每个page确立一个唯一标识。

2、创建存放page唯一标识符的数组。

3、类构造函数私有并实现单例。

4、数组中倒数两个唯一标识的page,在build()和deactivate()函数中自定义onResume()、onPause()。

Page导航管理:

import 'package:flutter/material.dart';import 'base_widget.dart';class NavigatorManger {List<String> _activityStack = new List<String>();NavigatorManger._internal();static NavigatorManger singleton = new NavigatorManger._internal();//工厂模式factory NavigatorManger() => singleton;//添加唯一标识到数组中void addWidget(BuildContext context) {print("BaseWidget__" + context.toString());_activityStack.add(getClassName(context));}//移除唯一标识void removeWidget(BuildContext context) {_activityStack.remove(getClassName(context));}//通过上下文获取page唯一标识String getClassName(BuildContext _buildContext) {if (_buildContext == null) {return null;}String className = _buildContext.toString();if (className == null) {return null;}className = className.substring(0, className.indexOf("(")).toString();return className;}//通过数组中标识队列,判断page的位置(是唯一最顶部,还是唯一最顶部之下的第二个page)bool isTop(BuildContext context, int num) {if (_activityStack == null) {return false;}try {String className = getClassName(context);int stackLength = _activityStack.length;int curIndex = (stackLength >= num) ? (stackLength - num) : -1;String stackClassName = curIndex >= 0 ? _activityStack[curIndex] : null;return (stackClassName == null) ? false : (stackClassName == className);} catch (exception) {return false;}}bool isTopPage(BuildContext context) {return isTop(context, 1);}bool isSecondTop(BuildContext context) {return isTop(context, 2);}
}

BaseWidge基类:

import 'package:flutter/material.dart';import 'navigator_manger.dart';abstract class BaseWidget extends StatefulWidget {@overrideBaseWidgetState createState() {return getState();}BaseWidgetState getState();
}abstract class BaseWidgetState<T extends BaseWidget> extends State<T> {String curPage;String tag = "BaseWidgetState_";bool _onResumed = false; //页面展示标记bool _onPause = false; //页面暂停标记@overridevoid initState() {super.initState();onCreate();tag = tag + curPage + "_";print(tag + "initState\n");//添加page唯一标识到数组NavigatorManger().addWidget(context);}@overridevoid didChangeDependencies() {print(tag + "didChangeDependencies\n");super.didChangeDependencies();}@overrideWidget build(BuildContext context) {print(tag + "build\n");if (!_onResumed) {//初次加载 顶部pageif (NavigatorManger().isTopPage(context)) {_onResumed = true;onResume();}}return Scaffold(body: baseBuild(context),);}@overridevoid didUpdateWidget(T oldWidget) {print(tag + "didUpdateWidget\n");super.didUpdateWidget(oldWidget);}@overridevoid reassemble() {print(tag + "reassemble\n");super.reassemble();}@overridevoid deactivate() {print(tag + "deactivate\n");//仅次于顶部的pageif (NavigatorManger().isSecondTop(context)) {if (!_onPause) {onPause();_onPause = true;} else {onResume();_onPause = false;}//顶部page} else if (NavigatorManger().isTopPage(context)) {if (!_onPause) {onPause();}}super.deactivate();}@overridevoid dispose() {print(tag + "dispose\n");_onResumed = false;_onPause = false;//把改页面 从 页面列表中 去除NavigatorManger().removeWidget(context);onDes();super.dispose();}void onCreate() {}void onResume() {print(tag + "onResume\n");}void onPause() {print(tag + "onPause\n");}baseBuild(BuildContext context) {}void onDes() {}
}

注意的是:

initState()函数中添加page唯一标识符,那么就要在dispose()函数中进行page唯一标识符的删除(当page被销毁的时)。

总结:

作为一名开发者,不仅仅要呈现任何功能其表,更多的是用遵循编码规范加以变化使程序更优质。日积月累、仿佛实战,不管是原生开发还是任何一个混合开发的框架都需要更好的管理页面的生命周期,追求更好用户体验的同时也更好的将界面的呈现比作有生命的对象,遵循生老病死又到投胎转世。

Flutter BaseWidget资源下载

Flutter BaseWidget 实现onResume、onPause()相关推荐

  1. Android 再次探究Fragment在各种情况下的onResume与onPause

    之前写过一篇关于Fragment真正的onResume与onPause的文章,但是当时写的比较匆忙,并不是很严谨,导致问题多多,今天抽空更新下关于fragment在各种情况下的onResume与onP ...

  2. Flutter State 的生命周期

    本文主要介绍类比 Android 和 iOS,了解 Flutter State 的生命周期. 从 Android 或 iOS 转到 Flutter 开发,最让人疑惑的是 Flutter 如何处理生命周 ...

  3. 详解 Flutter State 生命周期

    一.说明 我们在开发 Android 或 iOS 中经常会用到页面的生命周期. Android Activity 生命周期: onCreate onStart onResume onPause onS ...

  4. fragment类onresume里面刷新操作处理

    今天项目中涉及fragment中嵌套多个fragment,但是要根据tag去展示对应的fragment,而不是默认展示的第一个fragment,如果使用activity很容易想到onpause(),o ...

  5. 开发日记-20190511 关键词 onStart()和onResume()存在的原因(猜测篇)

    我有言在先,今天这个是猜测篇,没有经过证实,有一定可能是我的瞎猜= =,明天等我证实玩会做出相应的修改,把真相呈现出来= = 很多时候真的很想偷懒,但是没办法,虽然今天看了一下午lol季后赛的比赛,晚 ...

  6. onResume无限循环

    今天在做权限申请,写完后,发现点界面上任何东西都无法响应,整个界面处于卡死状态. 查看Log,onResume和onPause在不停的执行,debug排查发现是因为请求权限导致的. 由于考虑到权限必须 ...

  7. Fragment实现类似activity onResume()功能,控制fragment可见与不可见

    众所周知,fragment的onResume()和onPause()方法是和activity绑定在一起的,此时fragment的onResume方法并不能确定在fragment切换前后台时会调用,而a ...

  8. Activity中onStart()和onResume()的区别

    分析了Android Activity中onStart()和onResume()的区别.分享给大家供大家参考,具体如下: 首先你要知道Activity的四种状态: ① Active/Runing 一个 ...

  9. Android知识点原理总结

    Activity 4种启动模式 要讲启动模式,先讲讲任务栈Task,它是一种用来放置Activity实例的容器,他是以栈的形式进行盛放,也就是所谓的先进后出,主要有2个基本操作:压栈和出栈,其所存放的 ...

最新文章

  1. 员工未回复群消息被罚200元,企业:符合公司规章制度
  2. 二进制的mysql怎么装_使用二进制演示MySQL安装步骤
  3. Jquery 选择器大全 【转载】
  4. Linux下修改root密码以及找回root密码的方法
  5. CRM和ERP的Sales Organization的映射关系
  6. 手把手教你启动若依前后端分离项目
  7. C#Repeater控件的使用
  8. 【转】数据库常用面试题
  9. 《Adobe Premiere Pro CC经典教程(彩色版)》——第2课 设置项目 2.1 开始
  10. .Net Framework3.5离线安装
  11. 【机器人学】机器人运动学基础
  12. 《Adobe Flash CS4中文版经典教程》——1 FLASH CS4快速入门1.1 启动Flash并打开文件...
  13. 巴菲特致股东的一封信:2007年
  14. 数字证书格式转换:.key和.crt转换成.pem格式
  15. Excel之MATCH和INDEX函数(零基础快速上手)
  16. c语言怎么让行末没有空格,新人提问:如何将输出时每行最后一个空格删除
  17. Android手机商城
  18. 鲲鹏arm服务器编译安装PaddlePaddle
  19. SEEK学习论坛-JavaWeb开发实训课题 (数据库MySQL+js+Ajax+Servlet)
  20. Java实验——定义一个类,该类中包含以下几个方法(静态):实现两个字符串数组的逆序排序,输出结果为字符串数组;求两个整形数组的交集;求两个浮点型数组的并集;

热门文章

  1. 如何从海量数据中,快速采集到你想要的数据?
  2. JDBC 快速入门JDBC 抽取JDBC工具类:JDBCUtils
  3. 告诉你成功需要“十商”? 智商/情商/逆商/德商/胆商...
  4. 智慧餐饮远程监控解决方案
  5. pair 的常见用法详解
  6. 线性代数逆矩阵和矩阵方程题目
  7. 习题11-1 网页跳转 uva821
  8. 在Azure 中国区如何备案? 了解前置审批/ICP备/ICP证/公安备案
  9. JVM之记忆集|卡表|写屏障
  10. 国内第三代半导体产业成为行业风口