Flutter BaseWidget 实现onResume、onPause()

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

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

Flutter BaseWidget 实现onResume、onPause()_第1张图片

Flutter BaseWidget 实现onResume、onPause()_第2张图片

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

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

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

 

Flutter BaseWidget 实现onResume、onPause()_第3张图片

 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()的效果。

Flutter BaseWidget 实现onResume、onPause()_第4张图片

思路:

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

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

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

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

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

Page导航管理:

import 'package:flutter/material.dart';

import 'base_widget.dart';

class NavigatorManger {
  List _activityStack = new List();

  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 {
  @override
  BaseWidgetState createState() {
    return getState();
  }

  BaseWidgetState getState();
}

abstract class BaseWidgetState extends State {
  String curPage;
  String tag = "BaseWidgetState_";
  bool _onResumed = false; //页面展示标记
  bool _onPause = false; //页面暂停标记

  @override
  void initState() {
    super.initState();
    onCreate();
    tag = tag + curPage + "_";
    print(tag + "initState\n");
    //添加page唯一标识到数组
    NavigatorManger().addWidget(context);
  }

  @override
  void didChangeDependencies() {
    print(tag + "didChangeDependencies\n");
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    print(tag + "build\n");
    if (!_onResumed) {
      //初次加载 顶部page
      if (NavigatorManger().isTopPage(context)) {
        _onResumed = true;
        onResume();
      }
    }
    return Scaffold(
      body: baseBuild(context),
    );
  }

  @override
  void didUpdateWidget(T oldWidget) {
    print(tag + "didUpdateWidget\n");
    super.didUpdateWidget(oldWidget);
  }

  @override
  void reassemble() {
    print(tag + "reassemble\n");
    super.reassemble();
  }

  @override
  void deactivate() {
    print(tag + "deactivate\n");
    //仅次于顶部的page
    if (NavigatorManger().isSecondTop(context)) {
      if (!_onPause) {
        onPause();
        _onPause = true;
      } else {
        onResume();
        _onPause = false;
      }
      //顶部page
    } else if (NavigatorManger().isTopPage(context)) {
      if (!_onPause) {
        onPause();
      }
    }
    super.deactivate();
  }

  @override
  void 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() {}
}

Flutter BaseWidget 实现onResume、onPause()_第5张图片

注意的是:

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

总结:

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

Flutter BaseWidget资源下载

 

你可能感兴趣的:(Flutter)