簡體   English   中英

Flutter 在選擇項目時不更新放置在對話框中的 DropdownButton

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM