Flutter 选择项目时,颤振不更新对话框中的下拉按钮

Flutter 选择项目时,颤振不更新对话框中的下拉按钮,flutter,Flutter,我有一个alertDialog,其中包含一个DropdownButton小部件。每当我单击下拉列表中的某个选项时,我都希望它显示选定的值。我在下面列出了代码以及2个屏幕截图 我相信这可能是关于颤振如何构建小部件的一个问题,因为当我将DropdownButton小部件放置在对话框之外时,它工作了,但是将它放置在alertDialog中会导致它失败。我还注意到,如果单击下拉按钮中的某个选项,然后退出并再次单击对话框,则所选项目将发生更改。但是,我希望所选的值可以更改,而用户不必先点击退出对话框,然后

我有一个alertDialog,其中包含一个DropdownButton小部件。每当我单击下拉列表中的某个选项时,我都希望它显示选定的值。我在下面列出了代码以及2个屏幕截图

我相信这可能是关于颤振如何构建小部件的一个问题,因为当我将DropdownButton小部件放置在对话框之外时,它工作了,但是将它放置在alertDialog中会导致它失败。我还注意到,如果单击下拉按钮中的某个选项,然后退出并再次单击对话框,则所选项目将发生更改。但是,我希望所选的值可以更改,而用户不必先点击退出对话框,然后再点击返回

^

上图是用户第一次单击时的对话框。起初,唯一选择的项目是“我无法帮助”。每当用户单击DropdownMenu小部件并选择其他选项(如“其他”)时,该值应更改

^

这些是用户可以在下拉菜单中单击的各种选项。当用户单击它时,菜单应该相应地更新

代码:

请注意,我已将_chosenValue定义为构建函数外部的全局变量

void\u showDecept(){
显示对话框(
上下文:上下文,
生成器:(BuildContext上下文){
返回警报对话框(
标题:新文本(“拒绝任命请求”),
内容:容器(
身高:100,
宽度:200,
子:列(
儿童:[
新文本(“请选择一个选项说明您拒绝的原因。”),
新下拉按钮(
值:_chosenValue,
下划线:Container(),
项目:[“我无法帮助”、“描述不清楚”、“在设置的日期和时间不可用”、“其他”].map((字符串值){
返回新的DropdownMenuItem(
价值:价值,
子项:新文本(值,样式:TextStyle(fontWeight:fontWeight.w500)),
);
}).toList(),
onChanged:(字符串值){
设置状态(){
_chosenValue=值;
});
},
)
],
),
),
行动:[
//通常是对话框底部的按钮
新扁平按钮(
子项:新文本(“关闭”),
按下:(){},
},
),
],
);
},
);
}

只需查看下面的示例,您必须使用statefulBuilder来更改状态

import 'dart:convert';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _chosenValue;
 
  void _showDecline() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
          builder: (BuildContext context, StateSetter setState){
            return AlertDialog(
            title: new Text("Decline Appointment Request"),
            content: Container(
              height: 100,
              width: 200,
              child: Column(
                children: <Widget>[
                  new Text("Please select an option for why you declined."),
                  new DropdownButton<String>(
                    hint: Text('Select one option'),
                    value: _chosenValue,
                    underline: Container(),
                    items: <String>[
                      'I\'m not able to help',
                      'Unclear description',
                      'Not available at set date and time',
                      'Other'
                    ].map((String value) {
                      return new DropdownMenuItem<String>(
                        value: value,
                        child: new Text(
                          value,
                          style: TextStyle(fontWeight: FontWeight.w500),
                        ),
                      );
                    }).toList(),
                    onChanged: (String value) {
                      setState(() {
                        _chosenValue = value;
                      });
                    },
                  )
                ],
              ),
            ),
            actions: <Widget>[
              // usually buttons at the bottom of the dialog
              new FlatButton(
                child: new Text("Close"),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
          },
                  
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
              child: Container(
          child: FlatButton(child: Text('Click'), onPressed: _showDecline),
        ),
      ),
    );
  }
}


导入'dart:convert';
进口“包装:颤振/材料.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回资料app(主页:HomePage());
}
}
类主页扩展了StatefulWidget{
@凌驾
_HomePageState createState()=>\u HomePageState();
}
类_HomePageState扩展状态{
字符串\u chosenValue;
void_showDecept(){
显示对话框(
上下文:上下文,
生成器:(BuildContext上下文){
返回状态生成器(
生成器:(BuildContext上下文,StateSetter setState){
返回警报对话框(
标题:新文本(“拒绝任命请求”),
内容:容器(
身高:100,
宽度:200,
子:列(
儿童:[
新文本(“请选择一个选项说明您拒绝的原因。”),
新下拉按钮(
提示:文本(“选择一个选项”),
值:_chosenValue,
下划线:Container(),
项目:[
“我帮不了你”,
"描述不清",,
'在设置的日期和时间不可用',
“其他”
].map((字符串值){
返回新的DropdownMenuItem(
价值:价值,
儿童:新文本(
价值
样式:TextStyle(fontWeight:fontWeight.w500),
),
);
}).toList(),
onChanged:(字符串值){
设置状态(){
_chosenValue=值;
});
},
)
],
),
),
行动:[
//通常是对话框底部的按钮
新扁平按钮(
子项:新文本(“关闭”),
已按下:(){
Navigator.of(context.pop();
},
),
],
);
},
);
},
);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:安全区(
子:容器(
子项:扁平按钮(子项:文本('Click'),按下时:_showDecend),
),
),
);
}
}

只要让我知道它是否有效。

setState将只更新当前状态窗口小部件的窗口小部件构建功能

您应该在showDialog中使用StatefulBuilder

对于您的情况,只需将StatefulBuilder添加为下拉小部件的父级,并在需要更新StatefulBuilder的子级时使用StateSetter。 它将只更新StateFulBuilder函数下定义的小部件树


请参阅完整代码,包括DartPad代码中的stateFulBuilder

有关StatefulBuilder的更多信息,请访问
import 'dart:convert';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _chosenValue;
 
  void _showDecline() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
          builder: (BuildContext context, StateSetter setState){
            return AlertDialog(
            title: new Text("Decline Appointment Request"),
            content: Container(
              height: 100,
              width: 200,
              child: Column(
                children: <Widget>[
                  new Text("Please select an option for why you declined."),
                  new DropdownButton<String>(
                    hint: Text('Select one option'),
                    value: _chosenValue,
                    underline: Container(),
                    items: <String>[
                      'I\'m not able to help',
                      'Unclear description',
                      'Not available at set date and time',
                      'Other'
                    ].map((String value) {
                      return new DropdownMenuItem<String>(
                        value: value,
                        child: new Text(
                          value,
                          style: TextStyle(fontWeight: FontWeight.w500),
                        ),
                      );
                    }).toList(),
                    onChanged: (String value) {
                      setState(() {
                        _chosenValue = value;
                      });
                    },
                  )
                ],
              ),
            ),
            actions: <Widget>[
              // usually buttons at the bottom of the dialog
              new FlatButton(
                child: new Text("Close"),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
          },
                  
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
              child: Container(
          child: FlatButton(child: Text('Click'), onPressed: _showDecline),
        ),
      ),
    );
  }
}


import 'dart:convert';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _chosenValue;

  void _showDecline() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return AlertDialog(
              title: new Text("Decline Appointment Request"),
              content:
                  Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
                new Text("Please select an option for why you declined."),
                SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: new DropdownButton<String>(
                      hint: Text('Select one option'),
                      value: _chosenValue,
                      underline: Container(),
                      items: <String>[
                        'I\'m not able to help',
                        'Unclear description',
                        'Not available at set date and time',
                        'Other'
                      ].map((String value) {
                        return new DropdownMenuItem<String>(
                          value: value,
                          child: new Text(
                            value,
                            style: TextStyle(fontWeight: FontWeight.w500),
                          ),
                        );
                      }).toList(),
                      onChanged: (String value) {
                        setState(() {
                          _chosenValue = value;
                        });
                      },
                    )),
              ]),
              actions: <Widget>[
                // usually buttons at the bottom of the dialog
                new FlatButton(
                  child: new Text("Close"),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            );
          },
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          child: FlatButton(child: Text('Click'), onPressed: _showDecline),
        ),
      ),
    );
  }
}