Flutter ValueNotifier实际开发使用

Posted Xiao冰同学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter ValueNotifier实际开发使用相关的知识,希望对你有一定的参考价值。

ValueNotifier的实际使用

前言

Flutter弊端之一(也可以说是特色)就是大量使用了匿名对象,导致很难通过对象的引用去动态的修改对象状态,但是Flutter本质上就不太支持使用这种命令式开发,再加上Flutter是单向绑定,所以状态管理是比较麻烦。所以状态管理是Flutter开发难点之一。常用的状态管理框架有 Provider,Bloc等。但是轻量级的状态管理组件ValueNotifier是非常好用的,适用于一些常用小组件的封装,在实际业务开发中,非常适合于封装一些表单类的小组件,如日期选择器之类的。本文就二次封装一个日期选择器来讲解ValueNotifier的用法

开发环境

Flutter
1.22.0.stable

在pubspec.yaml中添加以下依赖

flutter_cupertino_date_picker_fork: 1.0.1
intl: 0.16.1

效果预览

设计思路

首先这个组件必须能够存储它当前的状态,并且能在父组件rebuild的时候,这个状态不会被改变,比如实现一个查询数据的功能页面,每次改变了时间,都要重新向服务器发送一次请求,然后让数据表格使用最新查询的数据,有可能会导致这个时间控件也会rebuild,如果这个时间控件也被rebuild (这个控件默认初始化为当前时间,但是用户选择了明天的时间,但是因为代码设计的问题,可能也会导致这个控件被rebuild,从而让这个控件的状态值变成了当前时间,这就会让人感到很疑惑了)
其次在一些表单填写的页面中,需要在点击提交按钮之后,获取到这个组件的值

实现要求

  1. 能通过点击提交按钮,获取到这个组件的值
  2. 能监听到这个组件的值的改变,并且能设置监听回调

代码实现

封装代码

time_date_selector.dart

import 'package:flutter/material.dart';
import 'package:flutter_cupertino_date_picker_fork/flutter_cupertino_date_picker_fork.dart';
import 'package:intl/intl.dart';

typedef onDateTimePicked = Function(DateTime DateTime);

typedef onSzDateTimePicked = Function(String szDateTime);

class DateTimeSelector extends StatefulWidget 

  ValueNotifier<String> notifier;

  String pattern;

  onDateTimePicked onPicked;

  onSzDateTimePicked onSzPicked;

  double fontSize;

  DateTimeSelector(
    this.notifier,
    this.onPicked,
    this.onSzPicked,
    this.fontSize: 14.0,
    this.pattern: 'yyyy-MM-dd');

  @override
  _DateTimeSelectorState createState() => _DateTimeSelectorState();


class _DateTimeSelectorState extends State<DateTimeSelector> 

  @override
  Widget build(BuildContext context) 
    return ValueListenableBuilder<String>(
        valueListenable: widget.notifier,
        builder: (BuildContext context, String value, Widget child) 
          return Container(
            child: InkWell(
              onTap: () => _showDatePicker(),
              child: Row(
                children: [
                  Icon(Icons.calendar_today, color: Color.fromRGBO(0, 149, 219, 1)),
                  Text(
                    value ?? '',
                    style: TextStyle(
                    fontSize: widget.fontSize,
                    color: Color.fromRGBO(0, 149, 219, 1)
                  )
                )
              ],
            ),
          )
        );
      
    );
  

  void _showDatePicker() 
    DatePicker.showDatePicker(
      context,
      pickerTheme: DateTimePickerTheme(
        itemTextStyle: TextStyle(color: Color(0xFF000000)),
      ),
      initialDateTime: parseStrDateTime(widget.notifier.value, widget.pattern),
      dateFormat: widget.pattern,
      locale: DateTimePickerLocale.zh_cn,
      onConfirm: (DateTime dateTime, List<int> index) 
        widget.notifier.value = formatDateTime(dateTime, widget.pattern);
        if (widget.onPicked != null)
          widget.onPicked(dateTime);
        if (widget.onSzPicked != null)
          widget.onSzPicked(widget.notifier.value);
      ,
    );
  



DateTime parseStrDateTime(String dateTime, String pattern) 
  DateFormat format = DateFormat(pattern);
  return format.parse(dateTime);


String formatDateTime(DateTime dateTime, String pattern) 
  DateFormat format = DateFormat(pattern);
  return format.format(dateTime);

使用示例

class DemoPage extends StatelessWidget 
  ValueNotifier<String> dateNotifier = ValueNotifier<String>(formatDateTime(DateTime.now(), 'yyyy-MM-dd'));
  ......
  DateTimeSelector(
  notifier: dateNotifier, 
  pattern: 'yyyy-MM-dd',
  onPicked: (DateTime date) 
    debugPrint(date.toString());  	//这里写监听回调函数
  ,
 )
 dateNotifier.value		// 获取值

总结

本质上其实ValueNotifier其实就是一个监听器,可以监听相对应的值得变化,存储组件得变量(状态),从而再不借助 Widget wd = new Widget(); w.value = “”; 这种命令式的代码来设置组件的状态。尤其是android / ios原生的同学在学习Flutter,会有诸多如此的不适,思维方式需要及时转变

以上是关于Flutter ValueNotifier实际开发使用的主要内容,如果未能解决你的问题,请参考以下文章

“ValueNotifier”+“ValueListenableBuilder”是不是适用于 Flutter 中的“许多”小部件?

Flutter ValueNotifier 倒计时 局部刷新组件 在StatelessWidget 中刷新倒计时

Flutter 异步加载多个函数一个接一个

如何在 Flutter 中添加多个相同类型的 ChangeNotifierProvider

Flutter 中 ChangeNotifier 的构建器小部件

Flutter 实现局部刷新 StreamBuilder 实例详解