简体   繁体   English

Flutter:如何使用提供者的 DropDownButton?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM