如何在Flutter中开始加载主题

我希望用户可以更改主题颜色并将其保存在我的应用中。但是,我不知道在应用程序开始运行时如何加载已保存的主题颜色。例如,我想直接在下面的注释位置加载保存的主题颜色。我尝试了SharedPreference。但是,SharedPreference实例需要与

await 一起运行。似乎无法在这里使用。有什么方法可以直接在这里加载保存的主题,而不是使用setState之类的东西?

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return new MaterialApp(

title: 'Flutter Demo',

theme: // how to load saved theme here?

),

home: new MyHomePage(title: 'Flutter Demo Home Page'),

);

}

}

回答:

这个答案更进一步。它显示了如何加载和保存主题首选项,如何构建ThemeData和如何从应用程序页面更改主题。


  • 使用shared_preferences插件保存用户首选项(选择了哪个主题)。
  • 使用整个Flutter框架中使用的“控制器模式”将当前选定的主题(及其更改)提供给您的应用。
  • 使用可以InheritedWidget在应用的任何部分使用控制器。

控制器的外观如下:

import 'package:flutter/material.dart';

import 'package:shared_preferences/shared_preferences.dart';

/// provides the currently selected theme, saves changed theme preferences to disk

class ThemeController extends ChangeNotifier {

static const themePrefKey = 'theme';

ThemeController(this._prefs) {

// load theme from preferences on initialization

_currentTheme = _prefs.getString(themePrefKey) ?? 'light';

}

final SharedPreferences _prefs;

String _currentTheme;

/// get the current theme

String get currentTheme => _currentTheme;

void setTheme(String theme) {

_currentTheme = theme;

// notify the app that the theme was changed

notifyListeners();

// store updated theme on disk

_prefs.setString(themePrefKey, theme);

}

/// get the controller from any page of your app

static ThemeController of(BuildContext context) {

final provider = context.inheritFromWidgetOfExactType(ThemeControllerProvider) as ThemeControllerProvider;

return provider.controller;

}

}

/// provides the theme controller to any page of your app

class ThemeControllerProvider extends InheritedWidget {

const ThemeControllerProvider({Key key, this.controller, Widget child}) : super(key: key, child: child);

final ThemeController controller;

@override

bool updateShouldNotify(ThemeControllerProvider old) => controller != old.controller;

}

这是您将控制器和InheritedWidget应用程序使用的方式:

void main() async {

// load the shared preferences from disk before the app is started

final prefs = await SharedPreferences.getInstance();

// create new theme controller, which will get the currently selected from shared preferences

final themeController = ThemeController(prefs);

runApp(MyApp(themeController: themeController));

}

class MyApp extends StatelessWidget {

final ThemeController themeController;

const MyApp({Key key, this.themeController}) : super(key: key);

@override

Widget build(BuildContext context) {

// use AnimatedBuilder to listen to theme changes (listen to ChangeNotifier)

// the app will be rebuilt when the theme changes

return AnimatedBuilder(

animation: themeController,

builder: (context, _) {

// wrap app in inherited widget to provide the ThemeController to all pages

return ThemeControllerProvider(

controller: themeController,

child: MaterialApp(

title: 'Flutter Demo',

theme: _buildCurrentTheme(),

home: MyHomePage(),

),

);

},

);

}

// build the flutter theme from the saved theme string

ThemeData _buildCurrentTheme() {

switch (themeController.currentTheme) {

case "dark":

return ThemeData(

brightness: Brightness.dark,

primarySwatch: Colors.orange,

);

case "light":

default:

return ThemeData(

brightness: Brightness.light,

primarySwatch: Colors.blue,

);

}

}

}

class MyHomePage extends StatefulWidget {

@override

_MyHomePageState createState() => _MyHomePageState();

}

class _MyHomePageState extends State<MyHomePage> {

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: new AppBar(),

body: Center(

child: Column(

children: <Widget>[

RaisedButton(

onPressed: () {

// thanks to the inherited widget, we can access the theme controller from any page

ThemeController.of(context).setTheme('light');

},

child: Text('Light Theme'),

),

RaisedButton(

onPressed: () {

ThemeController.of(context).setTheme('dark');

},

child: Text('Dark Theme'),

)

],

),

),

);

}

}

以上是 如何在Flutter中开始加载主题 的全部内容, 来源链接: utcz.com/qa/399472.html

回到顶部