Flutter偏好设置管理插件notified_preferences的使用

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

Flutter偏好设置管理插件notified_preferences的使用

notified_preferences 是一个用于读取和写入键值对的Flutter插件。它是 shared_preferences 的封装,提供了监听偏好设置值变化的简便方法。

Index

Usage

Getting started

为了开始使用 notified_preferences,你需要创建一个自定义的 Settings 类,并初始化它。以下是一个简单的例子:

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

class Settings with NotifiedPreferences {
  late final PreferenceNotifier<bool> hasSeenTutorial =
      createSetting(key: 'hasSeenTutorial', initial: false);

  late final PreferenceNotifier<int> clicked =
      createSetting(key: 'buttonClicks', initial: 0);
}

Future<void> main() async {
  Settings settings = Settings();
  await settings.initialize();
  runApp(
    // 使用 Provider 或其他方式注入你的 settings
    Provider.value(
      value: settings,
      child: MyApp(),
    ),
  );
}

Widgets

你可以使用 ValueListenableBuilder 来监听偏好设置的变化:

ValueListenableBuilder<int>(
  valueListenable: settings.clicked,
  builder: (context, value, child) => Text('You have clicked the button $value times!'),
)

当改变值时,所有监听器将被通知并重新构建:

FloatingActionButton(
  onPressed: () => settings.clicked.value++,
  tooltip: 'Increment',
  child: const Icon(Icons.add),
),

Listeners

你也可以通过 addListener 监听偏好设置的变化:

void _onClicked() {
  print('The user has clicked ${settings.clicked.value} times!');
}

settings.clicked.addListener(_onClicked);

记得在适当的时候移除监听器以避免内存泄漏:

@override
void dispose() {
  settings.clicked.removeListener(_onClicked);
  super.dispose();
}

Json

对于非基本类型的数据,可以将其作为 JSON 存储:

late final PreferenceNotifier<ComplexObject> complexObject = createJsonSetting(
  key: 'complexObject',
  initialValue: ComplexObject(
    someInt: 0,
    someString: 'a',
  ),
  fromJson: (json) => ComplexObject.fromJson(json),
);

Enums

对于枚举类型,提供了便利的方法:

late final PreferenceNotifier<SomeEnum> someEnum = createEnumSetting(
  key: 'someEnum',
  initialValue: SomeEnum.a,
  values: SomeEnum.values,
);

Advanced usage

Custom shared prefs

如果你已经在使用其他 SharedPreferences 封装库(如 encrypted_shared_preferences),或想要为测试模拟实现,可以在初始化时传递不同的 SharedPreferences 实现:

await settings.initialize(otherSharedPrefs);

Manual notifiers

如果不使用 NotifiedPreferences,可以手动实例化 PreferenceNotifier

final myNotifier = PreferenceNotifier<T>(
  preferences: preferences,
  key: key,
  initialValue: initialValue,
  read: read,
  write: write,
);

注意,这样会失去清除所有设置的功能。

Custom Read/Write

如果需要在读写偏好设置时实现自定义逻辑:

late final PreferenceNotifier<ComplexObject> complexObject = createSetting(
  key: 'complexObject',
  initialValue: ComplexObject(
    someInt: 0,
    someString: 'a',
  ),
  read: (prefs, key) {
    String? value = prefs.getString(key);
    ComplexObject? result;
    if (value != null) {
      result = ComplexObject.fromJson(jsonDecode(value));
    }
    return result;
  },
  write: (prefs, key, value) => prefs.setStringOrNull(
    key,
    json.encode(value.toJson()),
  ),
);

注意,read 方法不能是异步的。

Decentralised settings

如果你想在多个类中存储偏好设置,可以使用 NotifiedSettings

NotifiedSettings settings = await NotifiedSettings.getInstance();

class SomeController {
  final ValueNotifier<String?> someValue = settings.createSettings(
    key: 'someString',
    initialValue: null,
  );
}

这样可以保留清除所有设置的能力。

示例代码

以下是完整的示例代码,展示了如何使用 notified_preferences

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

class Settings with NotifiedPreferences {
  late final PreferenceNotifier<int> clicked =
      createSetting(key: 'buttonClicks', initial: 0);
}

class SettingsProvider extends InheritedWidget {
  final Settings settings;

  const SettingsProvider({
    Key? key,
    required this.settings,
    required Widget child,
  }) : super(key: key, child: child);

  static Settings of(BuildContext context) =>
      context.dependOnInheritedWidgetOfExactType<SettingsProvider>()!.settings;

  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) => true;
}

Future<void> main() async {
  Settings settings = Settings();
  await settings.initialize();
  runApp(
    SettingsProvider(
      settings: settings,
      child: const MyApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Notified Preferences Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            ValueListenableBuilder<int>(
              valueListenable: SettingsProvider.of(context).clicked,
              builder: (context, value, child) => Text(
                '$value',
                style: Theme.of(context).textTheme.headline4,
              ),
            ),
          ],
        ),
      ),
      bottomNavigationBar: Padding(
        padding: const EdgeInsets.all(8),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              'Close the app and reopen it to see your state persist.',
            ),
            TextButton(
              onPressed: SettingsProvider.of(context).clicked.reset,
              child: const Text('RESET'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => SettingsProvider.of(context).clicked.value++,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

这个示例展示了如何使用 notified_preferences 创建、初始化和监听偏好设置,并在UI中反映这些设置的变化。


更多关于Flutter偏好设置管理插件notified_preferences的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter偏好设置管理插件notified_preferences的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用notified_preferences插件来管理偏好设置的示例代码。notified_preferences是一个Flutter插件,用于管理应用的偏好设置,并允许监听设置的变化。

首先,确保你已经在pubspec.yaml文件中添加了notified_preferences依赖:

dependencies:
  flutter:
    sdk: flutter
  notified_preferences: ^x.y.z  # 替换为最新版本号

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

接下来,我们来看一个完整的示例,展示如何使用notified_preferences来管理应用的偏好设置。

1. 初始化NotifiedPreferences

在你的应用入口文件(通常是main.dart)中,初始化NotifiedPreferences实例:

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化NotifiedPreferences
  final NotifiedPreferences preferences = await NotifiedPreferences.instance;

  runApp(MyApp(preferences: preferences));
}

class MyApp extends StatelessWidget {
  final NotifiedPreferences preferences;

  MyApp({required this.preferences});

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

2. 使用NotifiedPreferences管理设置

在你的主页面(MyHomePage.dart)中,使用NotifiedPreferences来读取和写入设置,并监听设置的变化:

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

class MyHomePage extends StatefulWidget {
  final NotifiedPreferences preferences;

  MyHomePage({required this.preferences});

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late String themeModeKey = 'theme_mode';
  late ThemeMode _currentThemeMode;

  @override
  void initState() {
    super.initState();

    // 读取当前主题模式
    _currentThemeMode = widget.preferences.get(themeModeKey, defaultValue: ThemeMode.system) as ThemeMode;

    // 监听主题模式变化
    widget.preferences.addListener(themeModeKey, (key, value) {
      setState(() {
        _currentThemeMode = value as ThemeMode;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Notified Preferences Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Theme Mode: ${describeEnum(_currentThemeMode)}',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 切换主题模式
                ThemeMode newThemeMode = _currentThemeMode == ThemeMode.light
                    ? ThemeMode.dark
                    : ThemeMode.light;
                widget.preferences.set(themeModeKey, newThemeMode);
              },
              child: Text('Switch Theme Mode'),
            ),
          ],
        ),
      ),
    );
  }
}

3. 应用主题模式

为了让主题模式生效,你需要在MaterialApp中使用Builder组件来根据偏好设置更新主题:

class MyApp extends StatelessWidget {
  final NotifiedPreferences preferences;

  MyApp({required this.preferences});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.blueGrey,
      ),
      themeMode: widget.preferences.get('theme_mode', defaultValue: ThemeMode.system) as ThemeMode,
      builder: (context, child) {
        return NotifiedPreferencesListener(
          preferences: widget.preferences,
          keys: ['theme_mode'],
          builder: (context, preferences) {
            return Theme(
              data: ThemeData(
                brightness: preferences.get('theme_mode', defaultValue: ThemeMode.system) == ThemeMode.dark
                    ? Brightness.dark
                    : Brightness.light,
                primarySwatch: preferences.get('theme_mode', defaultValue: ThemeMode.system) == ThemeMode.dark
                    ? Colors.blueGrey
                    : Colors.blue,
              ),
              child: child!,
            );
          },
        );
      },
      home: MyHomePage(preferences: widget.preferences),
    );
  }
}

在这个示例中,我们使用了NotifiedPreferencesListener来监听theme_mode键的变化,并根据新的值更新应用的主题。

这样,你就完成了在Flutter项目中使用notified_preferences插件来管理偏好设置的基本示例。这个插件允许你轻松地读取、写入和监听应用偏好设置的变化。

回到顶部