Flutter类型安全偏好设置插件typed_preferences的使用

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

Flutter类型安全偏好设置插件typed_preferences的使用

简介

typed_preferences 提供了一个围绕 Shared Preferences 的类型安全包装,并带有额外的功能,如观察者(Observers)和数据访问对象(DAOs)。它旨在解决原生 Shared Preferences 在安全性及开发者体验方面的不足,通过创建一个简洁、表达性强且类型安全的 API。

功能特性

  • 类型安全:避免运行时类型错误。
  • 观察者模式:允许监听设置的变化。
  • DAO 支持:以面向对象的方式管理偏好设置。

安装与配置

首先,在 pubspec.yaml 文件中添加依赖:

dependencies:
  typed_preferences: ^最新版本号

然后执行 flutter pub get 来安装包。

使用方法

typed_preferences 主要包含四个组件:PreferencesDriverPreferencesDriverObserverTypedPreferencesDaoPreferencesEntry<T>。下面详细介绍如何使用这些组件。

Driver 配置

PreferencesDriver 是所有 DAO 操作的基础,通常在应用程序启动时创建并传递给各个 DAO。它不具有状态也不需要销毁。

import 'package:shared_preferences/shared_preferences.dart';
import 'package:typed_preferences/typed_preferences.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized(); // 确保初始化
  final preferences = await SharedPreferences.getInstance();
  
  final driver = PreferencesDriver(
    sharedPreferences: preferences,
    observers: const [LoggerPreferencesDriverObserver()], // 添加观察者
  );

  runApp(MyApp(driver: driver));
}

创建 DAO

DAO 是用来描述类似数据库表结构的类,其中每个字段都是类型安全的。通过继承 TypedPreferencesDao 并实现具体的 getter 方法来定义键值对。

class SettingsDao extends TypedPreferencesDao {
  SettingsDao(PreferencesDriver driver) : super(driver);

  @override
  String get name => 'settings'; // 可选地指定前缀

  PreferencesEntry<String> get userName => stringEntry('name');
  PreferencesEntry<int> get userAge => intEntry('age');
}

使用 DAO 进行读写操作

一旦设置了 DAO 和 Driver,就可以方便地进行数据存取了。

Future<void> main() async {
  // ... 初始化代码 ...

  final settingsDao = SettingsDao(driver);

  await settingsDao.userName.setValue('Joe'); // 设置字符串值
  await settingsDao.userAge.setValue(20);     // 设置整数值
  
  print(await settingsDao.userName.value);    // 获取并打印字符串值
  print(await settingsDao.userAge.value);     // 获取并打印整数值

  await settingsDao.userName.setValue('Jeff'); // 更新字符串值
  await settingsDao.userAge.setValue(30);      // 更新整数值
  
  print(await settingsDao.userName.value);    // 再次获取并打印更新后的字符串值
  print(await settingsDao.userAge.value);     // 再次获取并打印更新后的整数值
}

观察者模式

为了响应变化或记录日志,可以创建自定义的观察者类。这里展示了一个简单的日志记录器。

class LoggerPreferencesDriverObserver extends PreferencesDriverObserver {
  const LoggerPreferencesDriverObserver();

  void _log(void Function(StringBuffer b) logBuilder) {
    final buffer = StringBuffer('LoggerPreferencesDriverObserver | ');
    logBuilder(buffer);
    print(buffer.toString());
  }

  @override
  void onSet<T>(String path, T value, bool isSuccess) {
    super.onSet(path, value, isSuccess);
    _log(
      (b) => b
        ..write('Set ')
        ..write(path)
        ..write(' to value ')
        ..write(value)
        ..write(' ')
        ..write(isSuccess ? 'successfully' : 'unsuccessfully'),
    );
  }
}

这个例子展示了如何结合使用 typed_preferences 插件来实现类型安全的偏好设置管理,并通过观察者模式增强功能。希望这对您有所帮助!如果有任何问题或者需要进一步的帮助,请随时提问。


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

1 回复

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


当然,下面是一个关于如何使用 typed_preferences 插件的 Flutter 代码案例。typed_preferences 是一个用于 Flutter 的类型安全偏好设置插件,可以让你以类型安全的方式存储和读取应用偏好设置。

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

dependencies:
  flutter:
    sdk: flutter
  typed_preferences: ^2.0.0  # 请检查最新版本号

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

接下来是一个完整的 Flutter 应用示例,展示如何使用 typed_preferences

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

// 定义一个类型别名,方便后续使用
typealias AppPreferences = TypedPreferences<
  {
    'themeMode': ThemeMode,
    'username': String?,
    'isLoggedIn': bool,
  }
>;

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

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

class PreferencesScreen extends StatefulWidget {
  @override
  _PreferencesScreenState createState() => _PreferencesScreenState();
}

class _PreferencesScreenState extends State<PreferencesScreen> {
  late final AppPreferences preferences;

  @override
  void initState() {
    super.initState();
    preferences = TypedPreferences.builder<AppPreferences>()
      .withDefaultValues(
        ThemeMode.system,
        null,
        false,
      )
      .build();
  }

  void _updateThemeMode(ThemeMode newThemeMode) {
    preferences.update('themeMode', newThemeMode);
    // 可以在这里刷新UI,例如使用setState
  }

  void _updateUsername(String? newUsername) {
    preferences.update('username', newUsername);
    // 可以在这里刷新UI,例如使用setState
  }

  void _updateIsLoggedIn(bool newIsLoggedIn) {
    preferences.update('isLoggedIn', newIsLoggedIn);
    // 可以在这里刷新UI,例如使用setState
  }

  @override
  Widget build(BuildContext context) {
    final themeMode = preferences.get('themeMode');
    final username = preferences.get('username');
    final isLoggedIn = preferences.get('isLoggedIn');

    return Scaffold(
      appBar: AppBar(
        title: Text('Preferences Screen'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Theme Mode: ${themeMode.toString()}'),
            DropdownButton<ThemeMode>(
              value: themeMode,
              hint: Text('Select Theme Mode'),
              onChanged: _updateThemeMode,
              items: ThemeMode.values.map((mode) {
                return DropdownMenuItem<ThemeMode>(
                  value: mode,
                  child: Text(mode.toString()),
                );
              }).toList(),
            ),
            SizedBox(height: 16),
            Text('Username: $username'),
            TextField(
              decoration: InputDecoration(labelText: 'Username'),
              onSubmitted: (value) {
                _updateUsername(value);
              },
              controller: TextEditingController(text: username ?? ''),
            ),
            SizedBox(height: 16),
            Text('Is Logged In: $isLoggedIn'),
            Switch(
              value: isLoggedIn,
              onChanged: _updateIsLoggedIn,
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们定义了一个类型别名 AppPreferences,它包含 ThemeModeString?bool 三种类型的偏好设置。然后,在 PreferencesScreen 组件中,我们初始化 TypedPreferences 实例,并提供默认值。通过 _updateThemeMode_updateUsername_updateIsLoggedIn 方法,我们可以更新偏好设置的值。

注意:

  • TypedPreferences.builder<AppPreferences>().withDefaultValues(...) 用于初始化偏好设置并提供默认值。
  • preferences.get('key') 用于读取偏好设置的值。
  • preferences.update('key', newValue) 用于更新偏好设置的值。

这个示例展示了如何在 Flutter 应用中使用 typed_preferences 插件进行类型安全的偏好设置管理。希望这对你有所帮助!

回到顶部