[英]Flutter not updating DropdownButton placed within a dialog when item is selected
我有一個包含 DropdownButton 小部件的 alertDialog。 每當我單擊下拉列表中的一個選項時,我都希望它顯示選定的值。 我列出了下面的代碼以及 2 個屏幕截圖。
我相信這可能是 flutter 如何構建小部件的問題,因為當我將 DropdownButton 小部件放置在對話框之外時它起作用了,但是將它放在 alertDialog 中會導致它失敗。 我還注意到,如果我單擊 DropdownButton 中的一個選項,然后退出並再次單擊對話框,則所選項目將會更改。 但是,我希望更改選定的值,而無需用戶退出對話框然后再返回。
^
上圖是用戶第一次點擊時的對話框。 起初,唯一選擇的項目是“我無能為力”。 每當用戶單擊 DropdownMenu 小部件並選擇不同的選項(例如“其他”)時,此值都應該更改。
^
這些是用戶可以在下拉菜單中單擊的各種選項。 當用戶點擊它時,菜單應該相應地更新。
代碼:
請注意,我已將 _chosenValue 定義為構建 function 之外的全局變量。
void _showDecline() {
showDialog(
context: context,
builder: (BuildContext context) {
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>(
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: () {},
},
),
],
);
},
);
}
setState 只會更新當前 StatefulWidget 的 Widget Build function。
您應該在 showDialog 中使用 StatefulBuilder。
對於您的情況,只需將 StatefulBuilder 添加為 DropDown 小部件的父級,並在您想要更新 StatefulBuilder 的子級時使用 StateSetter。 它只會更新在 StateFulBuilder builder function 下定義的小部件樹。
請參閱 DartPad 代碼StateFulBuilderDartPad中包含stateFulBuilder的完整代碼。
有關 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:
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),
),
),
);
}
}
只需查看以下示例,您必須使用 statefulBuilder 更改 state。
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),
),
),
);
}
}
讓我知道它是否有效。
onTap: () {
///___________________________________________________________________
// Get.defaultDialog(
// title: " وضعیت دزدگیر",
// middleText: "پیام اعلام وضعیت دزدگیر ارسال گردد؟",
// titleStyle: TextStyle(
// color: mainColor2, fontWeight: FontWeight.bold, fontSize: 16),
// middleTextStyle:
// TextStyle(color: mainColor6.withOpacity(0.9), fontSize: 15),
// );
///----------------------------------------------------------------------
// showDialog(
// context: context,
// builder: (context) => AlertDialog(
// content: Column(
// children: <Widget>[
// TextField(
// decoration: InputDecoration(
// icon: Icon(Icons.account_circle),
// labelText: 'Username',
// ),
// ),
// TextField(
// obscureText: true,
// decoration: InputDecoration(
// icon: Icon(Icons.lock),
// labelText: 'Password',
// ),
// ),
// ],
// ),
// ),
// );
///___________________________________________________________________
List<DropdownMenuItem<String>> listDrop = [];
String selected=null;
void loadData() {
listDrop.add(new DropdownMenuItem(
child: new Text("پایدار"),
value:"555",
));
listDrop.add(
new DropdownMenuItem(
child: new Text("لحظه ای"),
value:"444",
),
);
}
loadData();
Alert(
context: context,
title: "تنظیمات خروجی شماره ۱",
// desc: ".",
// image: Image.asset(
// "assets/settings.png",
// scale: 5,
// ),
content: Directionality(
textDirection: TextDirection.rtl,
child: Center(
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextField(
keyboardType: TextInputType.text,
controller: _codeShargController,
decoration: InputDecoration(
labelText: 'نام خروجی',
hintText: '${out1.read('codeShargController')}',
),
),
SizedBox(height: 25.0),
Center(
child: DropdownButton(
underline: Container(
height: 1.5,
color: Colors.black26,
),
hint: Text("وضعیت عملکرد"),
items: listDrop,
isExpanded: true,
value: selected,
style: TextStyle(color: Colors.black, fontSize: 16),
onChanged: (newValue) {
selected = newValue;
// setState(() {});
setState(() { selected = newValue; });
},
),
),
SizedBox(height: 25.0),
],
),
),
),
// content: Column(
// children: <Widget>[
//
// SizedBox(height: 10.0),
//
// TextField(
//
// decoration: InputDecoration(
//
// icon: Icon(Icons.account_circle),
// labelText: 'Username',
// ),
// ),
// SizedBox(height: 10.0),
//
// TextField(
// obscureText: true,
// decoration: InputDecoration(
// icon: Icon(Icons.lock),
// labelText: 'Password',
// ),
// ),
// ],
// ),
buttons: [
DialogButton(
onPressed: () {
out1.write(
"codeShargController", _codeShargController.text);
Navigator.pop(context);
},
child: Text(
"ثبت",
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
]).show();
///___________________________________________________________________
嘗試這個......
在單獨的 dart 文件上實施警報並調用它。 這對我有用。
重要- 使用了以下下拉插件,因為 ui 對我來說更好......鏈接 - dropdown_button2:^1.2.2
在主頁上按如下方式調用警報。
import 'package:crmapp/pages/payment_history/payment_history_search_dialog.dart';
import 'package:flutter/material.dart';
class PaymentHistoryScreen extends StatefulWidget {
@override
_PaymentHistoryScreenState createState() => _PaymentHistoryScreenState();
}
class _PaymentHistoryScreenState extends State<PaymentHistoryScreen> {
ScrollController scrollController = new ScrollController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Setting up AppBar
appBar: AppBar(
title: Text('Payment History'),
),
// Body
body: Container(
// your code here - you can use onpressed method in the body also.here I used it for floating button
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return new PaymentHistorySearchDialog(); //call the alert dart
}
);
},
child: Container
(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(100)),
),
child: Icon(Icons.search_sharp, size: 32, color: Colors.white,)
)
),
);
}
然后按如下方式對警報 dart 進行編碼。
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class PaymentHistorySearchDialog extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return PaymentHistorySearchDialogState();
}
}
class PaymentHistorySearchDialogState extends State<PaymentHistorySearchDialog> {
String? selectedValue;
List<String> items = [
'All',
'Completed',
'Pending',
'Rejected',
];
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return new AlertDialog(
titlePadding: EdgeInsets.only(top: 20, left: 15, right: 15, bottom: 5),
contentPadding: EdgeInsets.only(
top: 15,
left: 15,
right: 15,
bottom: 5
),
title: Text(
'Search'.toUpperCase(),
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w600,
fontFamily: "medium",
)
),
content: Container(
width: double.infinity,
height: 220,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
DropdownButtonHideUnderline(
child: DropdownButton2(
hint: Text(
'Select Status',
style: TextStyle(
fontSize: 14,
),
),
items: items
.map((item) =>
DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
value: selectedValue,
onChanged: (value) {
setState(() {
selectedValue = value as String;
//Navigator.of(context).pop();
});
print(value);
// selectedValue = value as String;
},
buttonHeight: 30,
buttonWidth: double.infinity,
itemHeight: 40,
buttonDecoration: BoxDecoration(
// borderRadius: BorderRadius.circular(14),
border: Border(
bottom: BorderSide(width: 1, color: Colors.black38),
),
),
buttonPadding: const EdgeInsets.only(bottom: 5, top: 5),
),
)
],
),
)
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.