[英]Flutter: How to user a DropDownButton with provider?
我有一個 dropDownButton,其中我 select 是整個應用程序的主題。 我嘗試了兩種實際嘗試解決此問題的方法。 第一個是使用注釋行“Provider.of(context).toggleTheme();” 在“setState”中。 必須按照另一個線程中的建議將“聽”選項設置為“假”,但它不起作用。 第二個是在“Themes.dart”中調用“toggleTheme()”,以便以這種方式通知聽眾。 像這樣的 Dropdownbutton 的正確實現是什么。
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,),
],
),
);
}
}
主題.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
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(),
},
),
);
}
}
我設法通過從您的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);
}
在DropDown
onChanged
方法中使用上下文調用該方法:
onChanged: (ThemeOptions newValue) {
setState(() {
dropdownValue = newValue;
dropdownValue.callParentTheme(context);
print(newValue.themeColor);
});
},
希望有幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.