Flutter自带管理组件

1管理状态的最常见的方法:

方法

描述

自身状态管理

Widget管理自己的状态。

父组件管理子组件状态

父Widget管理子Widget状态。

混合管理

混合管理(父Widget和子Widget都管理状态)。

全局状态管理

使用第三方库进行全局状态管理

关于状态管理原则:
  • 如果状态是用户数据,如复选框的选中状态、滑块的位置,则该状态最好由父Widget管理。
  • 如果状态是有关界面外观效果的,例如颜色、动画,那么状态最好由Widget本身来管理。
  • 如果某一个状态是不同Widget共享的则最好由它们共同的父Widget管理。

建议:

在Widget内部管理状态封装性会好一些,而在父Widget中管理会比较灵活。有些时候,如果不确定到底该怎么管理状态,那么推荐的首选是在父widget中管理(灵活会显得更重要一些)。

2.组件自身管理自身状态

自己管理自己的状态比较简单, 参数在组件内部 , 同时 setState也在自己内部

flutter iOS 等待权限获取 flutter 登录状态管理_Text

import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}
 
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("组件自己管理自己状态"),
      ),
      body: SelfWidget(),
    );
  }
}
 
class SelfWidget extends StatefulWidget {
  @override
  _SelfWidgetState createState() => _SelfWidgetState();
}
 
class _SelfWidgetState extends State<SelfWidget> {
  bool _isActive = false;
  _handleTap() {
    setState(() {
      _isActive = !_isActive;
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        width: 200,
        height: 200,
        color: _isActive ? Colors.amber : Colors.blueAccent,
      ),
    );
  }
}

3. 父组件管理子组件

父组件将参数和方法传给子组件供子组件调用, 子组件调用方法其实是在父组件中setState了.
子组件可以是无状态组件, 因为它并没有管理自身状态

flutter iOS 等待权限获取 flutter 登录状态管理_flutter iOS 等待权限获取_02

说明形成条件:

  • 1.父组件必须是StatefulWidget
  • 2.父组件将参数和方法传给子组件供子组件调用
  • 3.子组件调用方法是父组件的函数(函数中写有setState),否则子组件StateLessWidget是不生效的

总结:简单说,子组件的OnTap方法,执行的函数是父组件的,父组件进行回调

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("父组件管理子组件状态"),
      ),
      body: ParentsWidget(),
    );
  }
}

class ParentsWidget extends StatefulWidget {
  @override
  _ParentsWidgetState createState() => _ParentsWidgetState();
}

class _ParentsWidgetState extends State<ParentsWidget> {
  bool _isActive = false;

  void _tapToChangeColor(v) {
    setState(() {
      _isActive = v;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SonWidget(isActive: _isActive, tapFunction: _tapToChangeColor);
  }
}

class SonWidget extends StatelessWidget {
  final bool isActive;
  final Function tapFunction;

  SonWidget({Key key, this.isActive, this.tapFunction}) : super(key: key);

  void _handleTap() {
    tapFunction(!isActive);
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        child: Container(
          width: 200,
          height: 200,
          color: isActive ? Colors.amber : Colors.blue,
        ),
        onTap: _handleTap,
      ),
    );
  }
}

4.混合管理

子组件是有状态组件, 那么它可被父组件管理, 也可以自己管理自己.

说明形成条件:

  • 1.父组件必须是StateFulWidget
  • 2.子组件必须是StateFulWidget

总结:父组件接管子组件一部分状态, 子组件再自己管理一些仅与自己相关的状态

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("混合管理"),
      ),
      body: ParentsWidget(),
    );
  }
}

class ParentsWidget extends StatefulWidget {
  @override
  _ParentsWidgetState createState() => _ParentsWidgetState();
}

class _ParentsWidgetState extends State<ParentsWidget> {
  bool _isActive = false; //这个状态是父组件管理的, 给子组件用
  void _tapToChangeColor(v) {
    setState(() {
      _isActive = v; //父组件接管管理的状态在此更新
    });
  }

  @override
  Widget build(BuildContext context) {
    return SonWidget(isActive: _isActive, tapFunction: _tapToChangeColor);
  }
}

class SonWidget extends StatefulWidget {
  final bool isActive;
  final Function tapFunction;
  SonWidget({Key key, this.isActive, this.tapFunction}) : super(key: key);
  @override
  _SonWidgetState createState() => _SonWidgetState();
}

class _SonWidgetState extends State<SonWidget> {
  bool _borderHighLight = false; //这个状态是自己管理的
  void _handleTap() {
    widget.tapFunction(!widget.isActive); //这个状态是父组件管理的
    setState(() {
      _borderHighLight = !_borderHighLight; //自己管理的状态在此更新
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        child: Container(
          width: 200,
          height: 200,
          child: Container(
            color: widget.isActive ? Colors.amber : Colors.blueAccent,
          ),
          decoration: BoxDecoration(
              border: Border.all(
                  color: _borderHighLight ? Colors.blueAccent : Colors.amber,
                  width: 10)),
        ),
        onTap: _handleTap,
      ),
    );
  }
}