Flutter——Provider

147 阅读3分钟
  • provider

provider嵌入了另一个插件Nested,而Nested解决了组件嵌套过深
  • Provider基本实现

数据能改变,但页面不会重载页面

1、user_model.dart 模型对象文件

class UserModel{
  String name  = "Jimi";
  void changname(){
    name = "hello";
    print(name);
  }
}
2、provider_example.dart 消费者文件
import 'package:demo02/provider_example/user_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("ProviderExample"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserModel>(builder: (_, userModel, child) {
              return Text(
                userModel.name,
                style: const TextStyle(color: Colors.red, fontSize: 20),
              );
            }),
            Consumer<UserModel>(builder: (_, userModel, child) {
              return Padding(
                padding: const EdgeInsets.all(20),
                child: ElevatedButton(
                    onPressed: () {
                      userModel.changname();
                    },
                    child: const Text("改变值")),
              );
            })
          ],
        ),
      ),
    );
  }
}

3、main文件
import 'package:demo02/provider_example/provider_example.dart';
import 'package:demo02/provider_example/user_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return Provider<UserModel>(
      create: (_) => UserModel(),
      child: const MaterialApp(
        debugShowCheckedModeBanner: false,
        home: ProviderExample(),
      ),
    );
  }
}

  • ChangeNotifier

notifyListeners() 通知消费者更新页面

1、user_model1.dart 模型对象文件

import 'package:flutter/material.dart';

class UserModel1 extends ChangeNotifier {
  String name = "Jimi";
  void changnane() {
    name = "hello";
    notifyListeners();
    print("------------------");
  }
}
2、change_nodeifier_provider_example.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './user_model1.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("ChaneNotifilerProviderExample"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserModel1>(builder: (_, userModel1, child) {
              return Text(
                userModel1.name,
                style: const TextStyle(color: Colors.red),
              );
            }),
            Consumer<UserModel1>(
              builder: (_, userModel1, child) {
                return Padding(
                  padding: const EdgeInsets.all(20),
                  child: ElevatedButton(
                      onPressed: () {
                        userModel1.changnane();
                      },
                      child: const Text("改变值11")),
                );
              },
            )
          ],
        ),
      ),
    );
  }
}
3、main文件
    return ChangeNotifierProvider<UserModel1>(
      create: (_) => UserModel1(),
      child: const MaterialApp(
        debugShowCheckedModeBanner: false,
        home: ChaneNotifilerProviderExample(),
      ),
    );

  • FutureProvider

有一个初始值,子组件可以使用该Future值告诉子组件使用新的值来进行重建 ,并且只会重建一次,然后显示future值, 最后按钮改变时不会重建页面,但值是已经改变了

1、user_model2.dart文件
class UserModel2 {
  UserModel2({this.name});
  String? name = "Jimi";
  Future<void> changeName() async {
    await Future.delayed(const Duration(milliseconds: 2000));
    name = "hello";
    print(name);
  }
}
2、user_future.dart
import './user_model2.dart';
class UserFuture{
  Future<UserModel2> asyncGetUserModel2() async{
    await Future.delayed(Duration(microseconds: 2000));
    return UserModel2(name: "获取新的数据");
  }
}
3、future_provider_example.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './user_model2.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("ProviderExample"),
      ),
      body: Center(
        
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserModel2>(builder: (_, userModel, child) {
              return Text(
                userModel.name ?? "",
                style: const TextStyle(color: Colors.red, fontSize: 20),
              );
            }),
            Consumer<UserModel2>(builder: (_, userModel, child) {
              return Padding(
                padding: const EdgeInsets.all(20),
                child: ElevatedButton(
                    onPressed: () {
                      userModel.changeName();
                    },
                    child: const Text("改变值")),
              );
            })
          ],
        ),
      ),
    );
  }
}
4、main文件
return FutureProvider(
        create: (_) => UserFuture().asyncGetUserModel2(),
        initialData: UserModel2(name: "hello"),
        child: const MaterialApp(
          debugShowCheckedModeBanner: false,
          home: FutureProviderExample(),
        ));
  • StreamProvider

类似Future ,但ui会根据getStreamUserModel传入的值进行改变,不会根据按钮触发model文件里的代码方法去改变ui

1、user_model3.dart文件
class UserModel3 {
  UserModel3({this.name});
  String? name = "Jimi";
  void changeName() {
    name = "hello";
    print(name);
  }
}
2、user_stream.dart
import './user_model3.dart';

class UserStream {
  Stream<UserModel3> getStreamUserModel() {
    return Stream<UserModel3>.periodic(
            Duration(milliseconds: 1000), (value) => UserModel3(name: "$value"))
        .take(10);
  }
}

3、stream_providr_example.dart
import 'package:demo02/stream_providr_example/user_model3.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class StreamProviderExample extends StatefulWidget {
  const StreamProviderExample({super.key});

  @override
  State<StreamProviderExample> createState() => _StreamProviderExampleState();
}

class _StreamProviderExampleState extends State<StreamProviderExample> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("ProviderExample"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserModel3>(builder: (_, userModel, child) {
              return Text(
                userModel.name ?? "",
                style: const TextStyle(color: Colors.red, fontSize: 20),
              );
            }),
            Consumer<UserModel3>(builder: (_, userModel, child) {
              return Padding(
                padding: const EdgeInsets.all(20),
                child: ElevatedButton(
                    onPressed: () {
                      userModel.changeName();
                    },
                    child: const Text("改变值")),
              );
            })
          ],
        ),
      ),
    );
  }
}

4、 main文件
return StreamProvider<UserModel3>(
        initialData: UserModel3(name: "hello"),
        create: (_) => UserStream().getStreamUserModel(),
        child: const MaterialApp(
          debugShowCheckedModeBanner: false,
          home: StreamProviderExample(),
        ));
  • MultiProvider

解决了嵌套问题

1、user_model4.dart
import 'package:flutter/material.dart';

class UserModel4 with ChangeNotifier {
  String name = "Jimi";
  int age = 18;
  void changeName() {
    name = "hello";
    age = 20;
    notifyListeners();
  }
}

2、multi_provider_example.dart
Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Consumer<UserModel1>(builder: (_, userModel, child) {
              return Text(
                userModel.name,
                style: const TextStyle(color: Colors.red, fontSize: 20),
              );
            }),
            Consumer<UserModel4>(builder: (_, userModel, child) {
              return Text(
                userModel.age.toString(),
                style: const TextStyle(color: Colors.red, fontSize: 20),
              );
            }),
            Consumer2<UserModel1, UserModel4>(
                builder: (_, userModel1, userMode4, child) {
              return Padding(
                padding: const EdgeInsets.all(20),
                child: ElevatedButton(
                    onPressed: () {
                      userModel1.changnane();
                      userMode4.changeName();
                    },
                    child: const Text("改变值14")),
              );
            })
          ],
        ),
      ),
3、main文件
 return MultiProvider(
      providers: [
        ChangeNotifierProvider<UserModel1>(
          create: (_) => UserModel1(),
        ),
        ChangeNotifierProvider<UserModel4>(create: (_) => UserModel4())
      ],
      child: const MaterialApp(
        debugShowCheckedModeBanner: false,
        home: MultiProviderExample(),
      ),
    );

消费者

1Provider.of<模型对象名>(context)
2Consumer 
    builed(context,模型对象名,子组件),
    child! 不想更新的ui就可以写在这个child
   Consumer2<A,B> //两个模型
3Selector