【问题标题】:Flutter dropdown text field颤振下拉文本字段
【发布时间】:2018-09-21 16:19:44
【问题描述】:

我还是 Flutter 的新手。是否有材料下拉列表文本字段的示例?我在Material Text Field 上看到了这个例子,但我在文档中没有找到关于如何实现它的任何地方。感谢您在这方面的帮助。

【问题讨论】:

  • 查看example
  • Raouf,感谢您提供视频链接,但这不是我想要的。我正在尝试创建一个看起来像所有其他材料设计输入的下拉菜单。例如,它有一个标签,当控件获得焦点时,标签将缩小到顶部并在失去焦点时展开。再次感谢您对此提供帮助。
  • 请具体明确您需要什么,您需要一个下拉菜单还是一个包含上述提示文本的纯文本字段?你举了一个和下拉无关的例子!

标签: text field dropdown flutter


【解决方案1】:

按照 Jeff Frazier 的回答,您可以使用 DropdownButton2 包中的 DropdownButton2 或 DropdownButtonFormField2 进行更多自定义。它基于 Flutter 的核心 DropdownButton,您可以根据需要自定义更多选项。

【讨论】:

    【解决方案2】:

    您想要 DropdownButton 或 DropdownButtonFormField https://api.flutter.dev/flutter/material/DropdownButton-class.html

    和 DropdownMenuItem https://api.flutter.dev/flutter/material/DropdownMenuItem-class.html

    return DropdownButtonFormField(
      items: categories.map((String category) {
        return new DropdownMenuItem(
          value: category,
          child: Row(
            children: <Widget>[
              Icon(Icons.star),
              Text(category),
            ],
           )
          );
         }).toList(),
         onChanged: (newValue) {
           // do other stuff with _category
           setState(() => _category = newValue);
         },
         value: _category,
         decoration: InputDecoration(
           contentPadding: EdgeInsets.fromLTRB(10, 20, 10, 20),
             filled: true,
             fillColor: Colors.grey[200],
             hintText: Localization.of(context).category, 
             errorText: errorSnapshot.data == 0 ? Localization.of(context).categoryEmpty : null),
           );
    

    【讨论】:

      【解决方案3】:

      其他答案已经完全描述了您的需求,但这是一个将所有内容组合在一起的示例,这是一个可重复使用的下拉文本字段小部件,允许您指定任何类型的选项列表(不会丢失 dart 漂亮的类型系统) .

      class AppDropdownInput<T> extends StatelessWidget {
        final String hintText;
        final List<T> options;
        final T value;
        final String Function(T) getLabel;
        final void Function(T) onChanged;
      
        AppDropdownInput({
          this.hintText = 'Please select an Option',
          this.options = const [],
          this.getLabel,
          this.value,
          this.onChanged,
        });
      
        @override
        Widget build(BuildContext context) {
          return FormField<T>(
            builder: (FormFieldState<T> state) {
              return InputDecorator(
                decoration: InputDecoration(
                  contentPadding: EdgeInsets.symmetric(
                      horizontal: 20.0, vertical: 15.0),
                  labelText: hintText,
                  border:
                      OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
                ),
                isEmpty: value == null || value == '',
                child: DropdownButtonHideUnderline(
                  child: DropdownButton<T>(
                    value: value,
                    isDense: true,
                    onChanged: onChanged,
                    items: options.map((T value) {
                      return DropdownMenuItem<T>(
                        value: value,
                        child: Text(getLabel(value)),
                      );
                    }).toList(),
                  ),
                ),
              );
            },
          );
        }
      }
      

      你可以这样使用它:

      AppDropdownInput(
                  hintText: "Gender",
                  options: ["Male", "Female"],
                  value: gender,
                  onChanged: (String value) {
                    setState(() {
                      gender = value;
                      // state.didChange(newValue);
                    });
                  },
                  getLabel: (String value) => value,
                )
      

      【讨论】:

      • onValidate 你会怎么做?
      • 需要更新为空安全。
      【解决方案4】:

      更新:

      带有下拉菜单的文本表单字段

      var _currencies = [
          "Food",
          "Transport",
          "Personal",
          "Shopping",
          "Medical",
          "Rent",
          "Movie",
          "Salary"
        ];
      
       FormField<String>(
                builder: (FormFieldState<String> state) {
                  return InputDecorator(
                    decoration: InputDecoration(
                        labelStyle: textStyle,
                        errorStyle: TextStyle(color: Colors.redAccent, fontSize: 16.0),
                        hintText: 'Please select expense',
                        border: OutlineInputBorder(borderRadius: BorderRadius.circular(5.0))),
                    isEmpty: _currentSelectedValue == '',
                    child: DropdownButtonHideUnderline(
                      child: DropdownButton<String>(
                        value: _currentSelectedValue,
                        isDense: true,
                        onChanged: (String newValue) {
                          setState(() {
                            _currentSelectedValue = newValue;
                            state.didChange(newValue);
                          });
                        },
                        items: _currencies.map((String value) {
                          return DropdownMenuItem<String>(
                            value: value,
                            child: Text(value),
                          );
                        }).toList(),
                      ),
                    ),
                  );
                },
              )
      

      希望这会有所帮助!

      【讨论】:

      • 请也分享您的_currencies 变量。
      【解决方案5】:

      “下拉”可能不是您用来描述材料设计示例中提到的文本字段设计的正确词。

      下面是如何在 Flutter 中实现它:

      import 'package:flutter/material.dart';
      
      void main() {
        runApp(TextFieldExample());
      }
      
      class TextFieldExample extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Text Field Example',
            home: HomePage(),
            theme: ThemeData(
              primaryColor: Colors.deepPurple,
              accentColor: Colors.white,
            ),
          );
        }
      }
      
      class HomePage extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text('Text Field Example'),
            ),
            body: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                children: <Widget>[
                  //Material example
                  TextField(
                    decoration: InputDecoration(
                        filled: true,
                        hintText: 'Enter text',
                        labelText: 'Default text field'),
                    controller: new TextEditingController(),
                  ),
                  SizedBox(
                    height: 16.0,
                  ),
                  //Alternate
                  TextField(
                    decoration: InputDecoration(
                        border: OutlineInputBorder(),
                        hintText: 'Enter text',
                        labelText: 'Text field alternate'),
                    controller: new TextEditingController(),
                  ),
                ],
              ),
            ),
          );
        }
      }
      

      此示例应用包含两个不同的文本字段设计示例,可缩小和扩大相关标签。

      Gif of sample app - click here

      【讨论】:

        猜你喜欢
        • 2022-10-07
        • 1970-01-01
        • 1970-01-01
        • 2020-04-30
        • 1970-01-01
        • 2021-11-25
        • 2021-07-22
        • 1970-01-01
        • 2020-07-24
        相关资源
        最近更新 更多