Flutter框架 进阶一 Flutter-Habit 框架

Flutter-Habit诞生

Flutter-Habit
本文主要讲解,Flutter-Habit架构图解,全文架构,完全参照Android目前最流行的MVVM+DataBinding方式封装,目的旨在让客户端人员更加友好理解Flutter-Habit框架,进而能够进入快速开发

Flutter-基础功能拆解

  • base–提供基础组件,如缺省页,基础容器
  • constants–提供全局使用的常量、属性
  • helper–跨组件的全局属性
  • local–本地存储
  • network–网络管理,包括加解密
  • localizetion–多语言管理
  • utlis–工具类
  • widget–自定义控件
  • constant-config 配置文件
  • habit 插件交互管理
  • view_model 对外暴露
Flutter 核心功能讲解
  • BaseScaffold包括了几个核心的功能
    1.全局的ToolBar设置控制
  /// 设置ToolBar
  final Widget toolBar;

同时提供默认的ToolBar Widget

/// 获取当前的Toolbar的参数
  Widget _findCurrentToolBar() {
    /// 优先显示设置的toolBar
    if (widget.toolBar != null) {
      return widget.toolBar;
    }

    /// 显示默认的toolbar
    if (widget.toolBar == null && widget.viewModel.appBarIsShow) {
      return AppBarWidget(widget.viewModel);
    }
    return null;
  }

2.全局缺省页控制以及自定义

GestureDetector(
          behavior: HitTestBehavior.translucent,
          onTap: () {
            KeyboardUtils.hideByContext(context);
          },
          child: ValueListenableBuilder<EmptyState>(
            valueListenable: widget.viewModel.emptyState,
            builder: (context, state, _) => state == EmptyState.NORMAL
                ? widget.body
                : BaseEmptyStateWidget<VM>(
                    toolBar: widget.toolBar,
                  ),
          ),
        )

3.生命周期的监听

///页面生命周期
enum PageState {
  RESUMED,
  INACTIVE,
  PAUSED,
  DETACHED,
}
声明页面的生命周期,进行相关业务开发

由于本文基于Android Mvvm+Databinding模式进行Flutter开发,所以,这里数据监听方式使用的是ValueNotifier,以下以AppBarWidget进行一个简单描述

import 'package:flutter/material.dart';
import 'package:habit/example/widget/base_view_model.dart';
import 'package:habit/habit.dart';

///全局的ToolBar
class AppBarWidget extends StatelessWidget with PreferredSizeWidget {
  final BaseViewModel appBarProperty;

  AppBarWidget(this.appBarProperty);

  @override
  Widget build(BuildContext context) {
    return ValueListenableListBuilder(
      valueListenables: [
        appBarProperty.appBarTitle,
        appBarProperty.appBarShowBackIcon,
        appBarProperty.appBarBackIconColor,
        appBarProperty.appBarTitleColor,
        appBarProperty.appBarTitleSize,
        appBarProperty.appBarBgColor,
        appBarProperty.appBarBrightness,
        // appBarProperty.appBarLeadingCallBack
      ],
      builder: (context, value, child) {
        return AppBar(
          brightness: appBarProperty.appBarBrightness.value,
          backgroundColor: appBarProperty.appBarBgColor.value==null
              ? Theme.of(context).accentColor
              : appBarProperty.appBarBgColor.value,
          elevation: 0,
          centerTitle: true,
          title: Text(
            appBarProperty.appBarTitle.value,
            style: TextStyle(
              fontSize: appBarProperty.appBarTitleSize.value,
              color: appBarProperty.appBarTitleColor.value,
              fontWeight: FontWeight.bold,
            ),
          ),
          leading: Visibility(
            visible: appBarProperty.appBarShowBackIcon.value,
            child: IconButton(
              onPressed: () {
                // appBarProperty.appBarLeadingCallBack.value?.call();
                ///执行默认的返回按钮
                if (appBarProperty.appBarLeadingCallBack.value == null) {
                  Navigator.pop(context);
                } else {
                  appBarProperty.appBarLeadingCallBack.value.call();
                }
              },
              icon: Icon(
                Icons.arrow_back,
                color: appBarProperty.appBarBackIconColor.value,
                size: 25,
              ),
            ),
          ),
        );
      },
    );
  }

  @override
  Size get preferredSize => AppBar().preferredSize;
}

全文重点在于ValueListenableListBuilder,直接上源码

class ValueListenableListBuilder<T> extends StatefulWidget {
  const ValueListenableListBuilder({
    Key key,
    @required this.valueListenables,
    @required this.builder,
    this.child,
  })  : assert(valueListenables != null),
        assert(builder != null),
        super(key: key);
  ///看这里,这里是关键
  final List<ValueListenable<T>> valueListenables;

  final ValueListWidgetBuilder<T> builder;

  final Widget child;

  @override
  State<StatefulWidget> createState() => _ValueListenableListBuilderState<T>();
}

通过源码可以知道,ValueListenable用来监听数据改变,从而刷新UI,也就是我们常说的数据驱动UI。到这里,我们暂且思考下,Mvvm+livedata+databinding是不是也是这个模式?其实基本一毛一样了。

我随便写一个例子对比下,通过MutableLiveData绑定数据,继而在xml进行vm的绑定
xxviewModel.kt

  /**
     * 视频地址观察者
     */
    val videoUrl = MutableLiveData<String>(currentAlbum?.realPath)


 <com.example.widget.player.VideoPlayerView
            android:id="@+id/videoView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            binding:autoPlay="@{true}"
            binding:currentTimeTextView="@{current}"
            binding:layout_constraintBottom_toBottomOf="parent"
            binding:layout_constraintEnd_toEndOf="parent"
            binding:layout_constraintStart_toStartOf="parent"
            binding:layout_constraintTop_toTopOf="parent"
            binding:looping="@{true}"
            binding:playTag="@{viewModel.videoPlayTag}"
            binding:seekBar="@{progress}"
            binding:totalTimeTextView="@{total}"
            binding:videoUrl="@{viewModel.videoUrl}" />

等我写完,放源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Flutter-Habit[https://github.com/lianyagang/flutter-habit...
    馒Care阅读 1,396评论 5 9
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,869评论 2 59
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,557评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,607评论 0 11
  • 在妖界我有个名头叫胡百晓,无论是何事,只要找到胡百晓即可有解决的办法。因为是只狐狸大家以讹传讹叫我“倾城百晓”,...
    猫九0110阅读 3,335评论 7 3