FLUTTER学习笔记--状态管理


一、StatefulWidget

1.Flutter中的组件,按状态划分

  • StatefulWidget(无状态组件)
  • StatelessWidget(状态组件)

2.按状态作用域划分

  • 组件内私有状态(StatefulWidget)
  • 跨组间状态共享(InheritedWidget、Provider)
  • 全局状态(Redux|fish-redux、Mobx…)

3.状态组件的组成

  • StatefulWidget(组件本身不可变-@immutable)
  • State(将变化的状态放到State中维护)

4.代码

class CountPage extends StatefulWidget {
  @override
  State<CountPage> createState() => _CountPageState();
}

class _CountPageState extends State<CountPage> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child:Column(children: [
        Text("$count"),
        ElevatedButton(
          onPressed: () {
            setState(() {
              count++;
            });
          },
          child: Text("点击"),
        ),
      ],)
    );
  }
}

5.效果

1a59409f-f19e-4a84-a795-1cdb8c6a5530.gif

二、DataTable

1.DataTable是Flutter中的表格

  • columns(声明表头列表)
    • DataColumn(表头单元格)
  • rows(声明数据列表)
    • DataRow(一行数据)
      • DataCell(数据单元格)

2.代码

class User {
 String name;
 int age;
 bool selected;

 User(this.name, this.age, {this.selected = false});
}

class DataTableDemo extends StatefulWidget {
 const DataTableDemo({Key? key}) : super(key: key);

 @override
 State<DataTableDemo> createState() => _DataTableDemoState();
}

class _DataTableDemoState extends State<DataTableDemo> {
 List<User> data = [
   User('hh', 18),
   User('xx', 19),
   User('kk', 21),
   User('ll', 10),
 ];
 var _sortAscending = true;

 List<DataRow> _getUsersRows() {
   List<DataRow> dataRows = [];
   for (int i = 0; i < data.length; i++) {
     dataRows.add(
       DataRow(
           selected: data[i].selected,
           onSelectChanged: (selected) {
             setState(() {
               data[i].selected = selected!;
             });
           },
           cells: [
             DataCell(Text('${data[i].name}')),
             DataCell(Text('${data[i].age}')),
             DataCell(Text('男')),
             DataCell(Text('--')),
           ]),
     );
   }
   ;
   return dataRows;
 }

 @override
 Widget build(BuildContext context) {
   return Container(
     child: SingleChildScrollView(
       scrollDirection: Axis.horizontal,
       child: DataTable(
         sortColumnIndex: 1,
         //按第一列(年龄)排序
         sortAscending: _sortAscending,
         dataRowHeight: 50,
         horizontalMargin: 20,
         columnSpacing: 100,
         columns: [
           DataColumn(label: Text('姓名')),
           DataColumn(
               label: Text('年龄'),
               numeric: true,
               onSort: (int columnIndex, bool asscending) {
                 setState(() {
                   _sortAscending = asscending;
                   if (asscending) {
                     data.sort((a, b) => a.age.compareTo(b.age));
                   } else {
                     data.sort((a, b) => b.age.compareTo(a.age));
                   }
                 });
               }),
           DataColumn(label: Text('性别')),
           DataColumn(label: Text('简介'))
         ],
         rows: _getUsersRows(),
         // [
         // DataRow(cells: [
         //   DataCell(Text('张三')),
         //   DataCell(Text('18')),
         //   DataCell(Text('男')),
         //   DataCell(Text('--'))
         // ]),
         // DataRow(cells: [
         //   DataCell(Text('张三')),
         //   DataCell(Text('18')),
         //   DataCell(Text('男')),
         //   DataCell(Text('--'))
         // ]),
         // DataRow(cells: [
         //   DataCell(Text('张三')),
         //   DataCell(Text('18')),
         //   DataCell(Text('男')),
         //   DataCell(Text('--'))
         // ])
         //],
       ),
     ),
   );
 }
}

3.效果

2774c6ad-5840-4ce4-a8e4-272751676f8a.gif

三、InheritedWidget

1.InheritedWidget提供了沿树向下,共享数据的功能,即子组件可以获取父组件(InheritedWidget的子类)的数据

2.BuildContext.dependOnIneheritedWidgetOfExactType< MyInheritedWidget >()

3.代码

class InheritedWidgetDemo extends StatefulWidget {
  const InheritedWidgetDemo({Key? key}) : super(key: key);

  @override
  State<InheritedWidgetDemo> createState() => _InheritedWidgetState();
}

class _InheritedWidgetState extends State<InheritedWidgetDemo> {
  int _num = 0;

  void _increment() {
    setState(() {
      _num++;
    });
  }

  void _decrement() {
    setState(() {
      _num--;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ShareDataWidget(
      num: _num,
      child: Center(
        child: Column(
          children: [
            ElevatedButton(onPressed: _decrement, child: Text('-')),
            Padding(padding: EdgeInsets.all(20), child: Mycounter()),
            ElevatedButton(
              onPressed: _increment,
              //child: Icon(Icons.add)
              //跨组间访问数据
              child: Icon(Icons.add)
            )
          ],
        ),
      ),
    );
  }
}

class Mycounter extends StatefulWidget {
  const Mycounter({Key? key}) : super(key: key);

  @override
  State<Mycounter> createState() => _MycounterState();
}

class _MycounterState extends State<Mycounter> {
  @override
  Widget build(BuildContext context) {
    return Text(ShareDataWidget.of(context).num.toString());
  }
}

//数据共享组件
class ShareDataWidget extends InheritedWidget {
  final int num;

  const ShareDataWidget({
    required this.num,
    Key? key,
    required Widget child,
  }) : super(key: key, child: child);

  static ShareDataWidget of(BuildContext context) {
    final ShareDataWidget? result =
        context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
    assert(result != null, 'No ShareDataWidget found in context');
    return result!;
  }

  @override
  bool updateShouldNotify(ShareDataWidget oldWidget) {
    return true;
  }
}

4.效果

f1562474-eb10-4a63-a846-ea3fac539476.gif

四、生命周期

1.生命周期

  • initState()组件对象插入到元素树中时
  • didChangeDependencies()当前状态对象的依赖改变时
  • build()组件渲染时
  • setState()组件对象的内部状态变更时
  • didUpdateWidget()组件配置更新时
  • deactivate()组件对象在元素树中暂时移除时
  • dispose()组件对象在元素树中永远移除时

2.代码

class lifecycleDemo extends StatefulWidget {
  const lifecycleDemo({Key? key}) : super(key: key);

  @override
  State<lifecycleDemo> createState() => _lifecycleDemoState();
}

class _lifecycleDemoState extends State<lifecycleDemo> {
  int _num = 0;

  //通常根据后台接口的返回值数据对状态进行初始化
  @override
  void initState(){
    super.initState();
    print("init state");
    _num=1;
  }

  @override
  void didChangeDependencies(){
    super.didChangeDependencies();
    print("didChangeDependencies");
  }

  @override
  void didUpdateWidget(covariant lifecycleDemo oldWidget){
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget");
  }

  @override
  void deactivate(){
    super.deactivate();
    print("deactivate");
  }

  @override
  void dispose(){
    super.dispose();
    print("dispose");
  }

  void _increment() {
    setState(() {
      print('set state');
      _num++;
    });
  }

  void _decrement() {
    setState(() {
      print('set state');
      _num--;
    });
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    return Center(
      child: Column(
        children: [
          ElevatedButton(
              onPressed: _decrement,
              child: Text('-')
          ),
          Padding(
              padding: EdgeInsets.all(20),
              child: Text('$_num')
          ),
          ElevatedButton(
              onPressed: _increment,
              child: Icon(Icons.add)
          )
        ],
      ),
    );
  }
}

3.效果

80d8fcc8-fe06-4054-b386-03652d23633d.gif

五、Provider

1.Provider是对InheritedWidget的封装

2.优点

  • 简化资源的分配与处置
  • 懒加载

3.需要引入import’package.dio/dio.dart’

4.代码

main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: _HomePage(),
    );
  }
}

class _HomePage extends StatelessWidget {
  const _HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    //2.创建注册数据类型
    return ChangeNotifierProvider(
        create: (BuildContext context) => new LikesModel(),
        child: Scaffold(
          appBar: AppBar(
            title: const Text("learn1"),
            elevation: 10.0,
            centerTitle: true,
          ),
          body: providerDemo(),
        ));
  }
}

class LikesModel extends ChangeNotifier{
  int _counter=0;
  int get counter=>_counter;
  incrementCounter(){
    _counter++;
    //提供UI更新
    notifyListeners();
  }
}

class providerDemo extends StatelessWidget {
  const providerDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        //3.在子组件中使用数据模型
        children: [
          Text('${context.watch<LikesModel>().counter}'),
          TextButton(onPressed: Provider.of<LikesModel>(context).incrementCounter, child: Icon(Icons.thumb_up))
        ],
      ),
    );
  }
}

5.效果

2646e174-c3f6-4ecb-9ec9-e04ca3432bbf.gif

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值