0
点赞
收藏
分享

微信扫一扫

Flutter框架 进阶一 Flutter-Habit 框架

沪钢木子 2021-09-19 阅读 68

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,
}
声明页面的生命周期,进行相关业务开发
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}" />

等我写完,放源码

举报

相关推荐

0 条评论