繁体   English   中英

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

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

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