Flutter数据共享与管理插件flutter_provider的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter数据共享与管理插件flutter_provider的使用

介绍

flutter_provider 是一个由 Petrus Nguyễn Thái Học 开发的用于在Flutter中进行数据共享和管理的插件。它利用 InheritedWidget 提供了一种便捷的方式来暴露值,而无需自己编写 InheritedWidget

该库提供了以下特性:

  • 简单易用:只需要几行代码即可完成数据提供和消费。
  • 性能优化:通过 InheritedWidget 实现高效的数据传递。
  • 资源管理:支持定义 disposer 方法来清理资源。

相关链接


使用指南

添加依赖

首先,在你的 pubspec.yaml 文件中添加 flutter_provider 作为依赖项:

dependencies:
  flutter_provider: ^latest_version # 请替换为最新版本号

然后执行 flutter pub get 来安装依赖。

提供数据 (Provide Data)

要将数据提供给子组件,可以使用 ProvidersProvider<T>。下面是一个简单的例子:

final foo = Foo();
final bar1 = Bar1();

Providers(
  providers: [
    Provider<Bar1>.value(
      bar1,
      disposer: (v) => v.dispose(),
    ),
    Provider<Bar2>.factory(
      (context) => Bar2(),
      disposer: (v) => v.dispose(),
    ),
  ],
  child: Provider<Foo>.value(
    foo,
    disposer: (v) => v.dispose(),
    child: const HomePage(),
  ),
);

这里我们创建了两个 Provider,分别为 Bar1Bar2,并通过 Providers 将它们一起提供给子树中的 HomePage 组件。

消费数据 (Consume Data)

在需要访问这些数据的地方,你可以使用几种方式来获取它们:

  • 使用 Provider.of<T>(context)context.get<T>()
  • 使用 Consumer<T> 构建器模式来监听变化并重建UI

示例代码展示了如何在 HomePage 中同时消费多个类型的数据:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter provider example'),
      ),
      body: Consumer3<Foo, Bar1, Bar2>(
        builder: (BuildContext context, Foo a, Bar1 b, Bar2 c) {
          return Container(
            constraints: BoxConstraints.expand(),
            child: Center(
              child: Column(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Text(a.foo()),
                  Text(b.bar1()),
                  Text(c.bar2()),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

在这个例子中,Consumer3 同时监听了三种不同类型的数据,并根据它们的状态更新界面。

完整示例代码

// ignore_for_file: avoid_print

import 'package:flutter/material.dart';
import 'package:flutter_provider/flutter_provider.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Provider example',
      theme: ThemeData.dark(),
      home: const WelcomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        child: const Text('GO TO HOME'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute<void>(
              builder: (context) {
                final foo = Foo();
                final bar1 = Bar1();

                return Providers(
                  providers: [
                    Provider<Bar1>.value(
                      bar1,
                      disposer: (v) => v.dispose(),
                    ),
                    Provider<Bar2>.factory(
                      (context) => Bar2(),
                      disposer: (v) => v.dispose(),
                    ),
                  ],
                  child: Provider<Foo>.value(
                    foo,
                    disposer: (v) => v.dispose(),
                    child: const HomePage(),
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter provider example'),
      ),
      body: Consumer3<Foo, Bar1, Bar2>(
        builder: (BuildContext context, Foo a, Bar1 b, Bar2 c) {
          return Container(
            constraints: const BoxConstraints.expand(),
            child: Center(
              child: Column(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Text(a.foo()),
                  Text(b.bar1()),
                  Text(c.bar2()),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

class Foo {
  Foo() {
    print('$this::init');
  }

  String foo() => 'Hello';

  void dispose() => print('$this::dispose');
}

class Bar1 {
  Bar1() {
    print('$this::init');
  }

  String bar1() => 'Hello everyone';

  void dispose() => print('$this::dispose');
}

class Bar2 {
  Bar2() {
    print('$this::init');
  }

  String bar2() => 'Fall in love with Flutter';

  void dispose() => print('$this::dispose');
}

以上就是关于 flutter_provider 插件的基本介绍和使用方法。希望对你有所帮助!如果有任何问题或建议,请随时联系作者或者查看官方文档。


更多关于Flutter数据共享与管理插件flutter_provider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据共享与管理插件flutter_provider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,flutter_provider(或者更常见的 provider 包)是一个非常流行的状态管理解决方案,它允许在不同组件之间共享数据,而无需通过构造函数逐级传递。以下是一个使用 provider 包进行数据共享与管理的代码示例。

首先,确保在你的 pubspec.yaml 文件中添加 provider 依赖:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0  # 请检查最新版本号

然后运行 flutter pub get 来安装依赖。

创建一个数据模型

假设我们有一个简单的用户数据模型:

class User {
  final String name;
  final int age;

  User({required this.name, required this.age});
}

创建一个 ChangeNotifier 类

我们将创建一个 UserProvider 类来管理 User 对象的状态。这个类将继承自 ChangeNotifier,这样我们就可以在数据变化时通知监听者。

import 'package:flutter/material.dart';

class UserProvider with ChangeNotifier {
  User? _user;

  User? get user => _user;

  set user(User? newUser) {
    _user = newUser;
    notifyListeners();  // 通知监听者数据已更改
  }
}

在应用中设置 Provider

main.dart 文件中,我们需要使用 MultiProvider 来设置我们的 UserProvider

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'user_provider.dart'; // 假设 UserProvider 在这个文件中
import 'user_screen.dart'; // 假设我们的主屏幕在这个文件中

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => UserProvider()),
      ],
      child: MyApp(),
    ),
  );
}

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

在 UI 中使用 Provider

现在,我们可以在 UserScreen 中使用 ConsumerProvider.of<T>(context) 来访问和监听 UserProvider 的数据。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'user_provider.dart';

class UserScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('User Info'),
      ),
      body: Center(
        child: Consumer<UserProvider>(
          builder: (context, userProvider, child) {
            User? user = userProvider.user;
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Name: ${user?.name ?? 'Unknown'}'),
                Text('Age: ${user?.age ?? 0}'),
                SizedBox(height: 20),
                ElevatedButton(
                  onPressed: () {
                    // 更新用户数据
                    context.read<UserProvider>().user = User(name: 'John Doe', age: 30);
                  },
                  child: Text('Update User'),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

在这个例子中,我们使用 Consumer<UserProvider> 来监听 UserProvider 的状态变化,并在按钮点击时更新用户数据。注意,我们使用 context.read<UserProvider>().user 来读取数据(不触发重建),而使用 context.watch<UserProvider>() 则会监听数据变化并触发重建。

这就是使用 provider 包在 Flutter 中进行数据共享与管理的一个基本示例。根据你的具体需求,你可以进一步扩展和定制这个实现。

回到顶部