Flutter Provider局部刷新

本文详细介绍了Flutter中使用Provider进行状态管理的方法,包括如何添加依赖、创建ProviderModel、注册Provider以及局部刷新的实现。通过示例展示了如何在多个页面间共享并更新数据,以实现跨页面的状态同步。
摘要由CSDN通过智能技术生成

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<FirstProviderModel>(context).count}'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          Provider.of<FirstProviderModel>(context,listen: false).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }

}

通过Provider.of<FirstProviderModel>(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<FirstProviderModel>(context).count}'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          Provider.of<FirstProviderModel>(context,listen: false).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }

}


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

Flutter的`Provider`库是一个用于状态管理的库,它可以帮助你管理应用程序中的状态,并且可以在组件之间进行共享。当你在使用`Provider`库时,如果遇到动态刷新失效的问题,可能有以下几个原因: 1. 使用了错误的`Provider`类型:在使用`Provider`库时,你需要确保正确地使用了它的类型。例如,如果你想在组件之间共享一个`String`类型的值,你应该使用`TextableProvider`,而不是`Provider`。 2. 使用了不兼容的版本:在Flutter中,库的版本可能会影响其功能。如果你使用的库版本与`Provider`库不兼容,可能会导致动态刷新失效。请确保你使用的库版本与`Provider`库兼容。 3. 使用了错误的生命周期方法:在Flutter中,组件的生命周期非常重要。如果你在组件的生命周期方法中使用`Provider`库时出现问题,可能会导致动态刷新失效。请确保你在正确的方法中使用`Provider`库,并且按照正确的顺序调用相关方法。 4. 没有正确处理状态传递:在使用`Provider`库时,你需要正确地处理状态传递。例如,当你使用一个响应式的状态传递方式时,你可能需要确保你正确地注册了状态和更新。 要解决动态刷新失效的问题,你可以尝试以下方法: 1. 检查你的代码,确保你正确地使用了`Provider`库的类型和版本。 2. 检查你的组件生命周期方法是否正确。 3. 如果问题是由于响应式状态传递引起的,请确保你正确地注册了状态和更新。 4. 尝试使用不同的库或方法来解决你的问题,或者在社区中寻求帮助。 总之,动态刷新失效可能是由于多个原因引起的,你需要仔细检查你的代码和库版本,以确保你正确地使用了`Provider`库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值