[英]Flutter: How to user a DropDownButton with provider?
I have a dropDownButton where i select the theme for the entire app.我有一个 dropDownButton,其中我 select 是整个应用程序的主题。 I have tried two ways of actually trying to fix this.
我尝试了两种实际尝试解决此问题的方法。 First one was using the commented line "Provider.of(context).toggleTheme();"
第一个是使用注释行“Provider.of(context).toggleTheme();” in the "setState".
在“setState”中。 Had to make the "listen" option "false" as advised in another thread but it was not working.
必须按照另一个线程中的建议将“听”选项设置为“假”,但它不起作用。 And the second one was to just call the "toggleTheme()" inside the "Themes.dart" in order to notify listeners that way.
第二个是在“Themes.dart”中调用“toggleTheme()”,以便以这种方式通知听众。 What would be a correct implementation for a Dropdownbutton like this.
像这样的 Dropdownbutton 的正确实现是什么。
MainScreen.dart MainScreen.dart
import 'package:flutter/material.dart';
import 'package:thisismylastattempt/Misc/Themes.dart';
import 'package:provider/provider.dart';
class MainScreen extends StatefulWidget {
static const id = "main_screen";
@override
_MainScreenState createState() => _MainScreenState();
}
class ThemeOptions{
final Color themeColor;
final ThemeType enumTheme;
ThemeOptions({this.themeColor, this.enumTheme});
void callParentTheme(){
ThemeModel().changeEnumValue(enumTheme);
}
}
class _MainScreenState extends State<MainScreen> {
List<ThemeOptions> themes = [
ThemeOptions(themeColor: Colors.teal, enumTheme: ThemeType.Teal),
ThemeOptions(themeColor: Colors.green, enumTheme: ThemeType.Green),
ThemeOptions(themeColor: Colors.lightGreen, enumTheme: ThemeType.LightGreen),
];
ThemeOptions dropdownValue;
@override
void initState() {
dropdownValue = themes[0];
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('MainScreen'),
),
body: Column(
children: <Widget>[
Container(
child: DropdownButton<ThemeOptions>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(
color: Colors.deepPurple
),
underline: Container(
height: 0.0,
color: Colors.deepPurpleAccent,
),
onChanged: (ThemeOptions newValue) {
setState(() {
dropdownValue = newValue;
dropdownValue.callParentTheme();
print(newValue.themeColor);
//Provider.of<ThemeModel>(context).toggleTheme();
});
},
items: themes.map((ThemeOptions colorThemeInstance) {
return DropdownMenuItem<ThemeOptions>(
value: colorThemeInstance,
child: CircleAvatar(
backgroundColor: colorThemeInstance.themeColor,
),
);
})
.toList(),
),
),
SizedBox(height: 20.0,),
],
),
);
}
}
Themes.dart主题.dart
import 'package:flutter/material.dart';
enum ThemeType {Teal, Green, LightGreen}
ThemeData tealTheme = ThemeData.light().copyWith(
primaryColor: Colors.teal.shade700,
appBarTheme: AppBarTheme(
color: Colors.teal.shade700,
),
);
ThemeData greenTheme = ThemeData.light().copyWith(
primaryColor: Colors.green.shade700,
appBarTheme: AppBarTheme(
color: Colors.green.shade700,
),
);
ThemeData lightGreenTheme = ThemeData.light().copyWith(
primaryColor: Colors.lightGreen.shade700,
appBarTheme: AppBarTheme(
color: Colors.lightGreen.shade700,
),
);
class ThemeModel extends ChangeNotifier {
ThemeData currentTheme = tealTheme;
ThemeType _themeType = ThemeType.Teal;
toggleTheme() {
if (_themeType == ThemeType.Teal) {
currentTheme = tealTheme;
_themeType = ThemeType.Teal;
print('teal');
notifyListeners();
}
if (_themeType == ThemeType.Green) {
currentTheme = greenTheme;
_themeType = ThemeType.Green;
print('green');
notifyListeners();
}
if (_themeType == ThemeType.LightGreen) {
currentTheme = lightGreenTheme;
_themeType = ThemeType.LightGreen;
print('lightGreen');
notifyListeners();
}
}
ThemeType getEnumValue(){
return _themeType;
}
void changeEnumValue(ThemeType newThemeType){
_themeType = newThemeType;
toggleTheme();
}
}
main.dart main.dart
void main() => runApp(ChangeNotifierProvider<ThemeModel>(
create: (BuildContext context) => ThemeModel(), child: MyApp()));
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: AuthService().user,
child: MaterialApp(
theme: Provider.of<ThemeModel>(context).currentTheme,
title: 'Flutter Demo',
initialRoute: MainScreen.id,
routes: {
Wrapper.id: (context) => Wrapper(),
LoginPage.id: (context) => LoginPage(),
Registration.id: (context) => Registration(),
MainScreen.id: (context) => MainScreen(),
SwitchAuthenticationState.id: (context) =>
SwitchAuthenticationState(),
},
),
);
}
}
I managed to make it work by calling the changeEnumValue
from the Provider
in the callParentTheme
of your ThemeOptions
class:我设法通过从您的
ThemeOptions
class 的callParentTheme
中的Provider
调用changeEnumValue
来使其工作:
class ThemeOptions {
final Color themeColor;
final ThemeType enumTheme;
ThemeOptions({this.themeColor, this.enumTheme});
// void callParentTheme() {
// ThemeModel().changeEnumValue(enumTheme);
void callParentTheme(context) {
Provider.of<ThemeModel>(context, listen: false).changeEnumValue(enumTheme);
}
call the method with the context in your DropDown
onChanged
method:在
DropDown
onChanged
方法中使用上下文调用该方法:
onChanged: (ThemeOptions newValue) {
setState(() {
dropdownValue = newValue;
dropdownValue.callParentTheme(context);
print(newValue.themeColor);
});
},
Hope It's help希望有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.