Flutter本地数据存储插件shared_preferences_gen的使用

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

Flutter本地数据存储插件shared_preferences_gen的使用

shared_preferences_gen 是一个代码生成器,为 Flutter 的 shared_preferences 提供强类型访问器。

特性

  • 检查重复键
  • 对于 shared_preferences 提供类型安全的访问器
  • 支持以下类型:
    • DateTime
    • enum
    • 可序列化对象(具有 fromJson 构造函数和 toJson 方法)

如何使用

安装

确保将以下包添加到项目依赖中:

flutter pub add --dev build_runner
flutter pub add --dev shared_preferences_gen
flutter pub add shared_preferences_annotation

兼容性与 json_serializable

如果你正在使用 json_serializable,你需要在 build.yaml 文件中添加以下配置:

global_options:
  json_serializable:
    runs_before:
      - shared_preferences_gen

这将确保在分析代码时生成的 toJsonfromJson 方法可用。

添加导入和部分指令

确保在正确文件中指定部分指令。例如,在以下示例中,将 name 替换为你实际的文件名。

import 'package:shared_preferences_annotation/shared_preferences_annotation.dart';

part 'name.g.dart';

运行代码生成器

运行代码生成器的命令如下:

dart run build_runner build --delete-conflicting-outputs

创建共享偏好条目

要创建一个共享偏好条目,首先在你希望存储 SharedPreferences 实例的文件中创建一个 [@SharedPrefData](/user/SharedPrefData) 注解。然后添加带有其相应类型、键和默认值(可选)的条目。

SharedPrefEntry

SharedPrefEntry 可以用于以下类型:

  • bool
  • double
  • int
  • String
  • List<String>
  • DateTime
  • 任何 enum
  • 任何具有 toJson 方法和 fromJson 工厂构造函数的可序列化对象
[@SharedPrefData](/user/SharedPrefData)(entries: [
  SharedPrefEntry<String>(key: 'myKey'),
])
void main() { /* ... */ }

读取条目

你可以直接从 SharedPreferences 实例访问生成的条目。

final prefs = await SharedPreferences.getInstance();
String myKey = prefs.myKey.value;
bool darkMode = prefs.darkMode.value;

写入条目

final prefs = await SharedPreferences.getInstance();
await prefs.myKey.setValue('newValue');

删除条目

final prefs = await SharedPreferences.getInstance();
await prefs.myKey.remove();

路线图

  • 支持自定义对象(无预计时间)

示例代码

以下是 shared_preferences_gen 的一个完整示例:

import 'package:example/my_model.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:shared_preferences_annotation/shared_preferences_annotation.dart';

part 'main.g.dart';

const _defaultObj = MyModel(name: 'John', age: 21);

[@SharedPrefData](/user/SharedPrefData)(entries: [
  SharedPrefEntry<String>(key: 'title', defaultValue: 'Hello, World!'),
  SharedPrefEntry<bool>(key: 'darkMode', defaultValue: false),
  SharedPrefEntry<int>(key: 'numberOfVisits', defaultValue: 0),
  SharedPrefEntry<List<String>>(key: 'history', defaultValue: ['0', '1']),
  SharedPrefEntry<DateTime>(key: 'lastVisit'),
  SharedPrefEntry<ThemeMode>(key: 'themeMode', defaultValue: ThemeMode.system),
  SharedPrefEntry<MyModel>(key: 'myModel', defaultValueAsString: '_defaultObj'),
])
Future<void> main() async {
  final prefs = await SharedPreferences.getInstance();

  runApp(MainApp(prefs));
}

class MainApp extends StatelessWidget {
  const MainApp(this.prefs, {super.key});

  final SharedPreferences prefs;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(prefs),
    );
  }
}

class Home extends StatefulWidget {
  const Home(this.prefs, {super.key});

  final SharedPreferences prefs;

  [@override](/user/override)
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  [@override](/user/override)
  void initState() {
    super.initState();

    widget.prefs.lastVisit.setValue(DateTime.now());
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        padding: const EdgeInsets.all(16),
        itemCount: widget.prefs.entries.length,
        itemBuilder: (context, index) {
          final entry = widget.prefs.entries.elementAt(index);
          return ListTile(
            title: Text(entry.key),
            subtitle: Text(entry.value.toString()),
          );
        },
      ),
    );
  }
}

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

1 回复

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


当然,shared_preferences_gen 是 Flutter 的一个插件,用于生成类型安全的代码来访问 shared_preferences。相比于直接使用 shared_preferencesshared_preferences_gen 提供了一种更安全和类型严格的方式来管理本地存储的数据。

下面是一个简单的示例,展示如何使用 shared_preferences_gen 来进行本地数据存储。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 shared_preferencesshared_preferences_gen 依赖:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.0.15

dev_dependencies:
  build_runner: ^2.1.4
  shared_preferences_gen: ^2.0.3

2. 创建配置文件

接下来,创建一个 shared_preferences.yaml 文件来定义你的偏好设置类型。例如:

# shared_preferences.yaml

preferences:
  themeMode: String  # "light", "dark", or "system"
  fontSize: double   # Font size in the app
  isLoggedIn: bool   # User login status

3. 生成类型安全的代码

在项目根目录下运行以下命令来生成类型安全的代码:

flutter pub run build_runner build

这将生成一个 shared_preferences.g.dart 文件,其中包含了类型安全的偏好设置访问代码。

4. 使用生成的类型安全代码

下面是一个示例,展示如何在 Flutter 应用中使用生成的类型安全代码来读取和写入偏好设置:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:your_app_name/shared_preferences.g.dart'; // 注意导入生成的文件

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

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

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

class _PreferencesScreenState extends State<PreferencesScreen> {
  late SharedPreferencesPreferences _preferences;

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

  Future<void> initPreferences() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    _preferences = SharedPreferencesPreferences(sharedPreferences);

    // 初始化一些默认值(可选)
    if (_preferences.themeMode == null) {
      await _preferences.setThemeMode('light');
    }
    if (_preferences.fontSize == null) {
      await _preferences.setFontSize(16.0);
    }
    if (_preferences.isLoggedIn == null) {
      await _preferences.setIsLoggedIn(false);
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Preferences'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextFormField(
              initialValue: _preferences.themeMode ?? '',
              decoration: InputDecoration(labelText: 'Theme Mode'),
              onChanged: (value) async {
                await _preferences.setThemeMode(value);
              },
            ),
            SizedBox(height: 16),
            TextFormField(
              keyboardType: TextInputType.number,
              decoration: InputDecoration(labelText: 'Font Size'),
              inputFormatters: [
                FilteringTextInputFormatter.digitsOnly,
              ],
              onChanged: (value) {
                double? fontSize = double.tryParse(value);
                if (fontSize != null) {
                  _preferences.setFontSize(fontSize);
                }
              },
            ),
            SizedBox(height: 16),
            SwitchListTile(
              title: Text('Logged In'),
              value: _preferences.isLoggedIn ?? false,
              onChanged: (value) async {
                await _preferences.setIsLoggedIn(value);
              },
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,SharedPreferencesPreferences 类是由 shared_preferences_gen 生成的,它提供了类型安全的方法来读取和写入偏好设置。通过这种方式,你可以避免运行时类型错误,并使代码更加清晰和易于维护。

回到顶部