Flutter数据共享插件shared_value的使用

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

Flutter数据共享插件shared_value的使用

Flutter应用开发中,状态管理是一个重要的话题。shared_value插件提供了一种简洁、高效的方式来管理全局状态,它基于InheritedModel构建,允许开发者轻松地在Flutter应用中管理全局状态。下面我们将详细介绍如何使用shared_value插件,并通过一个完整的示例代码来展示其功能。

一、什么是Shared Value

SharedValue可以被视为对Provider状态管理方案的一种低样板(low-boilerplate)泛化。它将变量封装在一个智能的“容器”中,这个容器是Flutter感知的,也就是说,它可以自动处理状态的变化并通知依赖它的组件进行重建。

二、使用方法

1. 初始化

首先,需要声明SharedValue变量,并且非常重要的一点是:必须将其声明为final类型以防止意外覆盖SharedValue对象。例如:

// 这个全局的 SharedValue 可以在整个应用程序中共享
// 注意:变量被声明为 final 类型
final SharedValue<int> counter = SharedValue(
  // 初始值
  value: 0,
);

void main() {
  runApp(
    // 不要忘记这段初始化代码!
    SharedValue.wrapApp(
      MyApp(),
    ),
  );
}

2. 使用

与其它状态管理解决方案不同的是,SharedValue可以在任何期望的地方工作,甚至不需要BuildContext。你可以直接读取或更新SharedValue中的值:

void main() {
  // 读取 [counter]
  print(counter.$);

  // 更新 [counter]
  counter.$ += 1;
}

// 在 widgets 中使用 [counter],让 SharedValue 自动处理其余的事情。
Widget build(BuildContext context) {
  // .of(context) 会使得此 widget 在值变化时自动重建
  int counterValue = counter.of(context);

  return Text("Counter: $counterValue");
}

3. 持久化

如果希望将SharedValue的数据保存到磁盘上,可以通过指定key和设置autosave参数来实现:

// 提供一个 shared_prefences 的 key
final SharedValue<int> counter = SharedValue(
  // 磁盘存储 key 用于 shared_preferences (可选)
  key: "counter",

  // 当值发生变化时自动保存到 shared prefs (可选)
  autosave: true,
);

void main() async {
  // 从 shared preferences 加载 [counter] 的值
  await counter.load();

  // 将 [counter] 的值保存到 shared preferences (启用 `autosave` 会自动完成)
  await counter.store();
}

三、效率考量

SharedValue足够聪明,它只会重新构建那些订阅了更新的widgets,不会影响其他未订阅的部件,从而提高了性能。

四、完整示例代码

以下是一个完整的示例程序,展示了如何使用shared_value插件创建一个简单的计数器应用,该应用还包含了一个定时器,用来显示用户停留在页面的时间长度。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shared_value/shared_value.dart';

// 全局 SharedValue 可以在整个应用程序中共享
final SharedValue<int> counter = SharedValue(
  value: 0, // 初始值
  key: "counter", // 用于 shared_preferences 的磁盘存储 key
  autosave: true, // 当值改变时自动保存到 shared prefs
);

final SharedValue<Duration> randomValue = SharedValue(value: Duration.zero);

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 从 shared prefs 加载之前的值
  await counter.load();

  DateTime startedAt = DateTime.now();
  Timer.periodic(Duration(milliseconds: 50), (timer) {
    randomValue.$ = DateTime.now().difference(startedAt);
  });

  runApp(
    // 不要忘记这一步!
    SharedValue.wrapApp(
      MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("MyApp.build()");

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Shared value demo"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              CounterText(),
              Padding(
                padding: const EdgeInsets.all(32),
                child: RandomText(),
              ),
            ],
          ),
        ),
        floatingActionButton: CounterButton(),
      ),
    );
  }
}

class CounterText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // .of(context) 使得此 widget 在值变化时自动重建
    int counterValue = counter.of(context);

    print("CounterText.build() - $counterValue");

    return Text(
      '$counterValue',
      style: Theme.of(context).textTheme.headline4,
    );
  }
}

class CounterButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("Button.build()");

    return FloatingActionButton(
      onPressed: _incrementCounter,
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }

  void _incrementCounter() {
    // 更新 counter 值并重新构建 widgets
    counter.$ += 1;
  }
}

class RandomText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text("Your time here: ${randomValue.of(context)}");
  }
}

以上就是关于shared_value插件的基本介绍和使用方法。希望这些信息能够帮助你更好地理解和运用这个强大的工具,在你的Flutter项目中更方便地管理应用状态。如果你有任何疑问或者遇到问题,欢迎随时提问!


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

1 回复

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


当然,以下是如何在Flutter中使用shared_value插件进行数据共享的代码示例。请注意,shared_value可能不是Flutter社区广泛使用的标准插件,这里我们假设它是一个用于跨组件或页面共享数据的自定义插件,类似于Flutter的官方状态管理解决方案(如providerriverpod)或本地存储(如shared_preferences)。

不过,为了示范,我将以一个假设的shared_value插件为基础,展示如何在Flutter中共享数据。如果shared_value实际存在且有所不同,请参考其官方文档进行调整。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加shared_value依赖(假设它存在于pub.dev上,或者你已经有了这个插件的代码):

dependencies:
  flutter:
    sdk: flutter
  shared_value: ^x.y.z  # 替换为实际版本号

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

2. 初始化插件

在你的主应用文件(如main.dart)中,初始化并配置shared_value插件:

import 'package:flutter/material.dart';
import 'package:shared_value/shared_value.dart'; // 假设插件提供这个导入路径

void main() {
  // 初始化插件(假设有初始化方法)
  SharedValue.init();

  runApp(MyApp());
}

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

3. 共享数据

现在,让我们在两个不同的页面或组件之间共享数据。

3.1 设置数据

在第一个组件中设置共享数据:

import 'package:flutter/material.dart';
import 'package:shared_value/shared_value.dart'; // 假设插件提供这个导入路径

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              decoration: InputDecoration(labelText: 'Enter some text'),
              onChanged: (value) {
                // 设置共享值
                SharedValue.set('sharedText', value);
              },
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondPage()),
                );
              },
              child: Text('Go to Second Page'),
            ),
          ],
        ),
      ),
    );
  }
}

3.2 获取数据

在第二个组件中获取共享数据:

import 'package:flutter/material.dart';
import 'package:shared_value/shared_value.dart'; // 假设插件提供这个导入路径

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String? sharedText = SharedValue.get('sharedText'); // 获取共享值

    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: Text(
          sharedText ?? 'No shared text found',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

4. 运行应用

现在,运行你的Flutter应用,你应该能够在FirstPage中输入文本,并通过点击按钮导航到SecondPage,在那里显示之前输入的文本。

注意

  • 上述代码示例假设shared_value插件提供了init, set, 和 get 方法。如果实际插件的API不同,请参考其官方文档。
  • 如果shared_value不是一个实际存在的插件,你可以考虑使用Flutter的官方状态管理解决方案(如providerriverpod)或本地存储(如shared_preferences)来实现类似的功能。
回到顶部