Flutter Provider局部刷新

1.添加Provider依赖

dependencies:
  provider: ^4.0.4
  flutter:
    sdk: flutter

最新版本https://pub.dev/packages/provider

2.创建ProviderModel

class FirstProviderModel extends ChangeNotifier{
  int _count = 0;

  int get count => _count;

  void add() {
    _count++;
    print('$_count');
    notifyListeners();
  }
}

这是一个计数案例,_count属于私有化只能通过count调用、add是增加数值方法。

3.使用前需要注册ProviderModel
(1)单页面使用注册

///用来配置页面中的Provider
///仅当前页面使用
class FirstProviderStateless extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return  MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_)=>FirstProviderModel()),
      ],
      child: FirstProvider(),
    );
  }
}

(2)多页面使用注册(在main.dart中)

///MultiProvider配置在main里面才可以在页面之间通用
///配置在单个页面当中 数据不会刷新
main() {
  runApp(MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_)=>FirstProviderModel())
    ],
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: FirstProvider(),
    );
  }
}

两者区别:
单页面使用仅仅只是为了局部刷新使用。
多页面使用注册是为了多个页面改变值使用(例如A和B两个页面,a页面负责展示值 b页面既展示又要去修改这个值,这时在b页面修改值之后也会通知a页面的值进行改变)

4.注册完成之后如何局部刷新
想要达到局部刷新效果需要将要刷新的控件放在Consumer当中代码展示如下


class FirstProvider extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return FirstProviderState();
  }
}

class FirstProviderState extends State<FirstProvider>{
  ///刷新次数记录
  var _refreshTime = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('FirstProvider')),
        body:  getColumn(),

        floatingActionButton: FloatingActionButton(
          onPressed: (){
   
            //这句是为了修改model当中的值 当前直接进行修改值。
          	Provider.of<FirstProviderModel>(context,listen: false).add();
          	//这句是为了跳转下一个页面 完善两个页面共用一个值的需求。
            //Navigator.push(context, MaterialPageRoute(builder: (context) => SecondProvider()));
          },
          child: Icon(Icons.navigate_next),
        ),
    );
  }

  getColumn(){
    _refreshTime ++;
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
        ///包裹在Consumer中 才可以局部刷新这块
        Consumer<FirstProviderModel>(
          builder: (context, counter, child) => Text(
            '同步second页面值:${counter.count}',
          ),
        ),

        ///为了证明这里没刷新  刷新的话数值增加
        Container(
          alignment: Alignment.topCenter,
          child: Text('记录当前页面刷新次数:${_refreshTime}'),
        )
      ],
    );
  }

如上代码可以看出就需要局部刷新控件是放在Consumer当中,_refreshTime是为了标记在局部刷新时没有刷新其他控件。
counter相当于是最开始创建的ProviderModel

floatingActionButton跳转的是可点击增加计数的页面SecondProvider


class SecondProvider extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return SecondProviderState();
  }
}

class SecondProviderState extends State<SecondProvider>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('SecondProvider')),
      body: Center(
        child: Text('同步First页面值:${Provider.of(context).count}'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          Provider.of<FirstProviderModel>(context,listen: false).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }

}

通过Provider.of(context,listen: false).add();对model当中的数值进行修改。

完成代码
main.dart页面

///MultiProvider配置在main里面才可以在页面之间通用
///配置在单个页面当中 数据不会刷新
main() {
  runApp(MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_)=>FirstProviderModel())
    ],
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: FirstProvider(),
    );
  }
}

FirstProvider

///用来配置页面中的Provider
///仅当前页面使用
class FirstProviderStateless extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return  MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_)=>FirstProviderModel()),
      ],
      child: FirstProvider(),
    );
  }
}


class FirstProvider extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return FirstProviderState();
  }
}

class FirstProviderState extends State<FirstProvider>{
  ///刷新次数记录
  var _refreshTime = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('FirstProvider')),
        body:  getColumn(),

        floatingActionButton: FloatingActionButton(
          onPressed: (){
            Navigator.push(context, MaterialPageRoute(builder: (context) => SecondProvider()));
          },
          child: Icon(Icons.navigate_next),
        ),
    );
  }

  getColumn(){
    _refreshTime ++;
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
        ///包裹在Consumer中 才可以局部刷新这块
        Consumer<FirstProviderModel>(
          builder: (context, counter, child) => Text(
            '同步second页面值:${counter.count}',
          ),
        ),

        ///为了证明这里没刷新  刷新的话数值增加
        Container(
          alignment: Alignment.topCenter,
          child: Text('记录当前页面刷新次数:${_refreshTime}'),
        )
      ],
    );
  }

}

SecondProvider



///用来配置页面中的Provider
///仅当前页面使用
class SecondStateless extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => FirstProviderModel()),
      ],
      child: SecondProvider(),
    );
  }

}
class SecondProvider extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return SecondProviderState();
  }
}

class SecondProviderState extends State<SecondProvider>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('SecondProvider')),
      body: Center(
        child: Text('同步First页面值:${Provider.of(context).count}'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          Provider.of<FirstProviderModel>(context,listen: false).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }

}


以上就是本文全部内容,如有错误还请大家多多指正。

你可能感兴趣的:(flutter)