下拉菜单中的颤振设置状态不更新值

时间:2019-11-18 23:53:35

标签: android ios flutter state dropdownbutton

您好,我正在尝试更新警报对话框中的DropdownButton,但似乎未更新selectedValue。

这是代码:

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
final dbHelper = DataBaseHelper.instance;
int tabIndex = 1;
List<Characters> characters = List<Characters>();
List<Classes> dofusClass = List<Classes>();
String defaultValueSelect = "";

@override
void initState() {
super.initState();
populateCharacters();
getClasses();
}

@override
Widget build(BuildContext context) {

return Scaffold(
  appBar:
      AppBar(title: Text('Dofpedia'), backgroundColor: Colors.lightGreen),
  body: new Container(
      child: new Stack(
    children: <Widget>[
      Align(
        alignment: Alignment.topCenter,
        child: new IconButton(
          icon: Icon(CupertinoIcons.add, color: Colors.blue),
          onPressed: ()  {
             displayAndInput(context);
          },
        ),
      ),
      Padding(
        padding: const EdgeInsets.all(40.0),
        child: buildCharactersListView(context),
      ),
    ],
  )),
  bottomNavigationBar: new BottomNavigationBar(
    currentIndex: tabIndex,
    onTap: (int index) {
      setState(() {
        this.tabIndex = index;
      });
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => Equipments()),
      );
    },
    fixedColor: Colors.lightGreen,
    items: <BottomNavigationBarItem>[
      new BottomNavigationBarItem(
        icon: new Icon(CupertinoIcons.settings),
        title: new Text("Equipements"),
      ),
      new BottomNavigationBarItem(
        icon: new Icon(CupertinoIcons.profile_circled),
        title: new Text("Personnages"),
      ),
      new BottomNavigationBarItem(
        icon: new Icon(CupertinoIcons.book),
        title: new Text("Encyclopédie"),
      )
    ],
    ),
  );

  }

Future displayAndInput(BuildContext context) async{
TextEditingController tec = TextEditingController();
List<String> namesValues = dofusClass.map((f) => f.name).toList();
Characters c = new Characters();
return showDialog(
    context: context,
    builder: (context) {
      return AlertDialog(
        title: new Text("Nom du personnage"),
        content: new TextField(
          controller: tec,
        ),
        actions: <Widget>[
          Container(
            child: Column(
              children: <Widget>[
                DropdownButton<String>(
                  value: defaultValueSelect,
                  style: TextStyle(color: Colors.lightGreen),
                  underline: Container(
                    height: 1,
                    color: Colors.lightGreen,
                  ),
                  items: namesValues
                      .map<DropdownMenuItem<String>>((String value) {
                    return DropdownMenuItem<String>(
                      value: value,
                      child: Text(value)
                    );
                  }).toList(),
                  onChanged: (String newValue) {  
                      setState((){
                      defaultValueSelect = newValue;
                      c.type = newValue;
                      c.url = dofusClass.firstWhere((d)=> d.name == newValue).maleImg;
                      });
                  },
                ),
                FloatingActionButton.extended(
                  shape: new RoundedRectangleBorder(),
                  backgroundColor: Colors.lightGreen,
                  icon: Icon(Icons.save),
                  label: Text("Sauvegarde"),
                  onPressed: () {
                    //Sauvegarde dans la base de données
                    c.name = tec.value.text;
                    insertName(c);
                    Navigator.of(context).pop();
                    setState(() {
                      characters.add(c);
                    });
                  },
                ),
              ],
            ),
          )
        ],
      );
    });

SetState可以完美地与字符名配合使用。 当我更改选择值并单击输入名称时,下拉按钮选择的值将更新。

如果您有任何想法,欢迎您的帮助:)

编辑:抱歉缩进不好,稍后将尝试修复此问题:/

1 个答案:

答案 0 :(得分:1)

您需要使用StatefulBuilder包装AlertDialog
您可以在

下复制粘贴运行完整的测试代码

代码段

return showDialog(
        context: context,
        builder: (context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
            return AlertDialog(
              title: new Text("Nom du personnage"),
              content: new TextField(
                controller: tec,
              ),

工作演示

enter image description here

完整的测试代码

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyApp(),
    );
  }
}

class Characters {
  String type;
  String url;
  String name;

  Characters({
    this.type,
    this.url,
    this.name,
  });
}

class Classes {
  String name;
  String maleImg;

  Classes({this.name, this.maleImg});
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  //final dbHelper = DataBaseHelper.instance;
  int tabIndex = 1;
  List<Characters> characters = List<Characters>();
  List<Classes> dofusClass = List<Classes>();
  String defaultValueSelect = "abc";

  @override
  void initState() {
    super.initState();
    characters.add(Characters(type: "1", url: "abc", name: "def"));
    characters.add(Characters(type: "2", url: "ggg", name: "rrrr"));
    dofusClass.add(Classes(name: "abc", maleImg: "image1"));
    dofusClass.add(Classes(name: "def", maleImg: "image2"));
    //getClasses();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar:
          AppBar(title: Text('Dofpedia'), backgroundColor: Colors.lightGreen),
      body: new Container(
          child: new Stack(
        children: <Widget>[
          Align(
            alignment: Alignment.topCenter,
            child: new IconButton(
              icon: Icon(Icons.add, color: Colors.blue),
              onPressed: () {
                displayAndInput(context);
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(40.0),
            // child: buildCharactersListView(context),
          ),
        ],
      )),
      bottomNavigationBar: new BottomNavigationBar(
        currentIndex: tabIndex,
        onTap: (int index) {
          setState(() {
            this.tabIndex = index;
          });
          /*Navigator.push(
            context,
            //MaterialPageRoute(builder: (context) => Equipments()),
          );*/
        },
        fixedColor: Colors.lightGreen,
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
            icon: new Icon(Icons.settings),
            title: new Text("Equipements"),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.add),
            title: new Text("Personnages"),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.book),
            title: new Text("Encyclopédie"),
          )
        ],
      ),
    );
  }

  Future displayAndInput(BuildContext context) async {
    TextEditingController tec = TextEditingController();
    List<String> namesValues = ["abc","def"];//dofusClass.map((f) => f.name).toList();
    Characters c = new Characters();
    return showDialog(
        context: context,
        builder: (context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
            return AlertDialog(
              title: new Text("Nom du personnage"),
              content: new TextField(
                controller: tec,
              ),
              actions: <Widget>[
                Container(
                  child: Column(
                    children: <Widget>[
                      DropdownButton<String>(
                        value: defaultValueSelect,
                        style: TextStyle(color: Colors.lightGreen),
                        underline: Container(
                          height: 1,
                          color: Colors.lightGreen,
                        ),
                        items: namesValues
                            .map((String value) {
                          return DropdownMenuItem<String>(
                              value: value, child: Text(value));
                        }).toList(),
                        onChanged: (String newValue) {
                          setState(() {
                            defaultValueSelect = newValue;
                            c.type = newValue;
                            c.url = dofusClass
                                .firstWhere((d) => d.name == newValue)
                                .maleImg;
                          });
                        },
                      ),
                      FloatingActionButton.extended(
                        shape: new RoundedRectangleBorder(),
                        backgroundColor: Colors.lightGreen,
                        icon: Icon(Icons.save),
                        label: Text("Sauvegarde"),
                        onPressed: () {
                          //Sauvegarde dans la base de données
                          c.name = tec.value.text;
                          //insertName(c);
                          Navigator.of(context).pop();
                          setState(() {
                            characters.add(c);
                          });
                        },
                      ),
                    ],
                  ),
                )
              ],
            );
          });
        });
  }
}