Flutter:具有共享首选项和提供程序的 MVVM 架构

Flutter: MVVM architecture with Shared Preferences & Provider

我正在尝试使用 MVVM 架构构建共享首选项和提供程序的可重用功能。但是,我不确定如何在我的 main 中初始化 ChangeNotifierProvider。飞镖文件。 下面是我的代码。

class LanguagePreference {
  SharedPreferences prefs;

  LanguagePreference({required this.prefs});

  
  addUserLanguage(String lang) async {
    await SharedPreferences.getInstance();
    prefs.setString('userLanguage', "$lang");
  }

  
  getUserLanguage() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    //Return String
    return prefs.getString('userLanguage');
  }

}
  class LanguagePreferenceVM extends ChangeNotifier {
  LanguagePreference languagepreference;

  LanguagePreferenceVM({required this.languagePreference});

  String userLanguage = '';

  addUserLanguage(String newUserLanguage) async {
    await languagePreference.addUserLanguage(newUserLanguage);
  }

  getUserLanguage() async {
    userLanguage = await languagePreference.getUserLanguage();
    notifyListeners();
  }

  
}
 class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [],
      child: MaterialApp(
      ),
    );
  }
}

下面是一个综合示例。备注:

  • 不需要将 SharedPreferences 传递给您的模型,因为它有一个静态方法来获取实例。
  • 我使用 Provider.of<LanguagePreferenceVM> 让提供商更新语言。
  • 我使用 Consumer<LanguagePreferenceVM> 让提供商在通知听众时显示语言。
  • 我使用 FutureBuilder 来处理 async 结果。

示例代码:

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

class LanguagePreference {
  SharedPreferences _prefs;

  Future<void> getSharedPreferences() async {
    if (_prefs == null) {
      _prefs = await SharedPreferences.getInstance();
    }
  }

  LanguagePreference();

  Future<void> addUserLanguage(String lang) async {
    await getSharedPreferences();
    _prefs.setString('userLanguage', "$lang");
  }

  Future<String> getUserLanguage() async {
    //Return String
    try {
      await getSharedPreferences();
      var language = _prefs.getString('userLanguage');
      return language;
    } catch (e) {
      return '';
    }
  }
}

class LanguagePreferenceVM extends ChangeNotifier {
  LanguagePreference languagePreference;

  LanguagePreferenceVM({@required this.languagePreference});

  String userLanguage = '';

  Future<void> setUserLanguage(String newUserLanguage) async {
    await languagePreference.addUserLanguage(newUserLanguage);
    userLanguage = newUserLanguage;
  }

  Future<String> getUserLanguage() async {
    userLanguage = await languagePreference.getUserLanguage();
    return userLanguage;
  }
}

class PrefsTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<LanguagePreferenceVM>(
          create: (ctx) =>
              LanguagePreferenceVM(languagePreference: LanguagePreference()),
        ),
      ],
      child: PrefsTest2(),
    );
  }
}

class PrefsTest2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var languagePreferenceVM =
        Provider.of<LanguagePreferenceVM>(context, listen: false);
    languagePreferenceVM.setUserLanguage('English');
    return Scaffold(
      appBar: AppBar(title: Text('Prefs')),
      body: Consumer<LanguagePreferenceVM>(
        builder: (ctx, languagePreferenceVM, child) => FutureBuilder(
          future: languagePreferenceVM.getUserLanguage(),
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.waiting:
                return const CircularProgressIndicator();
              default:
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  return Text('User language: ${snapshot.data}');
                }
            }
          },
        ),
      ),
    );
  }
}