首页 > 解决方案 > 将 DropdownButtons 和 TextField 选定的数据保存到列表中

问题描述

我正在尝试创建一个 AlertDialog,它将接收来自这些 Alert 内部的 Dropdownbuttons 和 TextField 的 Future-List 或数据列表。在我的应用程序中,当我为 AlertDialog 调用这些函数时,将有 3 个 DropdownButtons 和 1 个 TextField,因此用户可以选择他想要的信息,然后当他从 AlerDialog 按“确定”时,他选择的数据将在里面列表,所以我可以将它与 Firestore 一起使用。

这是我的警报对话框:

Future<List> createAlertDialog(BuildContext context){

  return showDialog(context: context, builder: (ctx){
    return AlertDialog(
      title: Text('Text'),
      content: Column(
        children: [
          DropdownButton(
            value: iconNameSelected,
            items: iconlistdrop,
            hint: Text('Select Icon'),
            onChanged: (value) {
              iconNameSelected = value;
              setState(() {});
            },
          ),
          DropdownButton(
            value: activelabelSelected,
            items: activelistdrop,
            hint: Text('Select Active label'),
            onChanged: (value1) {
              activelabelSelected = value1;
              setState(() {});
            },
          ),
          DropdownButton(
            value: inactivelabelSelected,
            items: inactivelistdrop,
            hint: Text('Select InActive label'),
            onChanged: (value2) {
              inactivelabelSelected = value2;
              setState(() {});
            },
          ),
          TextField(
          ),
        ],
      ),
      actions: <Widget>[
        MaterialButton(
          elevation: 5.0,
          child: Text("OK"),
          onPressed: (){
            final values = [];
            Navigator.of(ctx).pop(values);
          },
        )
      ],
    );
  });
}

以下是我尝试在 InkWell 小部件中调用它的方式:

createAlertDialog(context).then((value){
   printf(value[0]);  
   printf(value[1]);
   printf(value[2]);
   printf(value[3]);
}

这是我在 DropdownButtons 中插入的数据中的一些额外内容:

List<DropdownMenuItem<String>> iconlistdrop = [];
List<DropdownMenuItem<String>> activelistdrop = [];
List<DropdownMenuItem<String>> inactivelistdrop = [];

String iconNameSelected = null;
String activelabelSelected = null;
String inactivelabelSelected = null;

void loadIcon () {
  iconlistdrop = [];
  iconlistdrop.add(DropdownMenuItem(
    child: Text('LightBulb'),
    value: 'lightbulbOutline',
  ));
  iconlistdrop.add(DropdownMenuItem(
    child: Text('Lock'),
    value: 'lock',
  ));
  iconlistdrop.add(DropdownMenuItem(
    child: Text('Check'),
    value: 'check',
  ));
}

void activelbl () {
  activelistdrop = [];
  activelistdrop.add(DropdownMenuItem(
    child: Text('On'),
    value: 'On',
  ));
  activelistdrop.add(DropdownMenuItem(
    child: Text('Locked'),
    value: 'Locked',
  ));
}

void inactivelbl () {
  inactivelistdrop = [];
  inactivelistdrop.add(DropdownMenuItem(
    child: Text('Off'),
    value: 'Off',
  ));
  inactivelistdrop.add(DropdownMenuItem(
    child: Text('Locked'),
    value: 'Unlocked',
  ));
}

loadIcon();
activelbl();
inactivelbl();

我的课:

class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
var temperature;
var humidity;

Future getWeather() async {
http.Response response = await 
 http.get('http://api.openweathermap.org/data/2.5/weather? 
q=Curitiba&units=metric&appid=8c1ce29a0b974e97562564d892cd5a97');
var results = jsonDecode(response.body);
setState(() {
  this.temperature = results['main']['temp'];
  this.humidity = results['main']['humidity'];
});
}

@override
void initState () {
this.getWeather();
super.initState();
}

@override
Widget build(BuildContext context) {

final AuthService _auth = AuthService();

final user = Provider.of<User>(context);

Future getSubCollection(){
  return Firestore.instance.collection('dadosusuarios').document(user.uid).collection('buttons').getDocuments(); 
}

标签: flutterdartflutter-layout

解决方案


我会为值使用映射并将对话框与另一个小部件分开,并给它一个构造函数,以防您可能希望它具有初始值。

import 'package:flutter/material.dart';

class MyAlertDialog extends StatefulWidget {
  final Map<String, dynamic> initialValues;
  const MyAlertDialog({
    Key key,
    this.initialValues,
  }) : super(key: key);
  @override
  _MyAlertDialogState createState() => _MyAlertDialogState();
}

class _MyAlertDialogState extends State<MyAlertDialog> {
  Map<String, dynamic> _values;
  TextEditingController _controller;
  @override
  initState() {
    super.initState();
    _values = widget.initialValues ??
        {'input1': 'One', 'input2': 'Two', 'input3': 'Free', 'input4': 'Four'};
    _controller = TextEditingController(text: _values['input4']);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Text'),
      content: Column(
        children: [
          DropdownButton(
            value: _values['input1'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select Icon'),
            onChanged: (value1) {
              setState(() {
                _values['input1'] = value1;
              });
            },
          ),
          DropdownButton(
            value: _values['input2'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select Active label'),
            onChanged: (value2) {
              setState(() {
                _values['input2'] = value2;
              });
            },
          ),
          DropdownButton(
            value: _values['input3'],
            items: <String>['One', 'Two', 'Free', 'Four']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
            hint: Text('Select InActive label'),
            onChanged: (value3) {
              setState(() {
                _values['input3'] = value3;
              });
            },
          ),
          TextField(
            controller: _controller,
          ),
        ],
      ),
      actions: <Widget>[
        MaterialButton(
          elevation: 5.0,
          child: Text("OK"),
          onPressed: () {
            _values['input4'] = _controller.text.trim();
            Navigator.of(context).pop(_values);
          },
        )
      ],
    );
  }
}

在这里我看看是否有从构造函数传递的值。如果不放一些默认值。使用每个用户输入更改更新地图,最后在弹出对话框后返回地图。我认为在这里使用 map 更好,并且可以更容易地将值推送到 Firestore。

 var result = await showDialog(
             context: context,
             builder: (ctx) {
         return MyAlertDialog(initialValues: /* Your default values if exist*/ );
                              });
 print(result);

推荐阅读