Flutter BaseWidget 实现onResume、onPause()

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

大家好,又见面了,我是你们的朋友全栈君。

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

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

Flutter BaseWidget 实现onResume、onPause()

Flutter BaseWidget 实现onResume、onPause()

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

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

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

 

Flutter BaseWidget 实现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()的效果。

Flutter BaseWidget 实现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 {
  @override
  BaseWidgetState 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; //页面暂停标记

  @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()

注意的是:

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

总结:

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

Flutter BaseWidget资源下载

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136934.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • accept text/html,Accept_标题 | Headers_HTTP_参考手册_非常教程

    accept text/html,Accept_标题 | Headers_HTTP_参考手册_非常教程AcceptAccept请求的HTTP标头通告了内容类型,并表示为MIME类型,客户端是能够理解的。使用内容协商,服务器然后选择其中一个提议,使用它并通过Content-Type响应头通知客户它的选择。浏览器根据请求完成的上下文为此标头设置足够的值:在获取CSS样式表时,为请求设置的值与获取图像,视频或脚本时的值不同。HeadertypeRequestheaderForbidden…

    2022年7月26日
    12
  • 设置页数自增页眉/页脚——Word中page域代码的使用

    设置页数自增页眉/页脚——Word中page域代码的使用本博文讲述如何在word中设置如图PageXofY格式的页眉/页脚,使其跟随页数自增首先添加页眉,选择好页眉样式。然后在页眉处写上:Page敲一下Ctrl+F9,会出现一对花括号:Page{}在其中填写“PAGE”,花括号外打上“of”:Page{PAGE}of再敲一下Ctrl+F9,在后面的花括号写上“sectionpages”Page{PAGE}of{sectionpages}退出页眉,按Alt+F9即可√(有时候要按两次)…

    2022年5月20日
    160
  • 碰撞检测经典解决方案

    碰撞检测经典解决方案碰撞检测在3D游戏中至关重要,好的碰撞检测要求人物在场景中可以平滑移动,遇到一定高度内的台阶可以自动上去,而过高的台阶则把人挡住,遇到斜率较小的斜坡可以上去,斜率过大则把人挡住,在各种前进方向被挡住的

    2022年7月3日
    37
  • 差异与阵列和阵列结构和链表的区别

    差异与阵列和阵列结构和链表的区别

    2022年1月14日
    40
  • Apache有哪两种虚拟主机的方式_服务器如何搭建虚拟主机

    Apache有哪两种虚拟主机的方式_服务器如何搭建虚拟主机Apache虚拟主机的实现方式有3种。基于IP的虚拟主机基于端口的虚拟主机基于域名的虚拟主机配置环境系统:CentOS7.5工具:XShell6**配置准备**1.安装httpdyuminstallhttpd-y2.查看安装了内容rpm-qlhttpd|less3、配置Selinux文件,SELINUX=disabled。4、关闭防火墙s…

    2022年9月17日
    2
  • Navicat15.0.25 激活码3月最新在线激活

    Navicat15.0.25 激活码3月最新在线激活,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    124

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号