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}');
}
}
},
),
),
);
}
}
我正在尝试使用 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}');
}
}
},
),
),
);
}
}