【问题标题】:Flutter combo box颤振组合框
【发布时间】:2018-05-14 17:13:01
【问题描述】:

我正在尝试创建一个下拉/组合框小部件并且很难弄清楚。下面是我尝试过的代码。基本上是创建一个我从这里和那里收集的列表,但无法将它相应地放入我自己的代码中。

import 'package:flutter/material.dart';

class Signup extends StatefulWidget{

  Signup({Key key}) : super (key:key);
  final String title;

  @override
  SignupPage createState() => new SignupPage();

}

class SignupPage extends State<Signup> {

@override
Widget build(BuildContext context) {
List _countrycodes = ["+65","+91"];
List<DropdownMenuItem<String>> _dropDownMenuItems;
String _selectedCountryCode;

List<String> _colors = <String>['', 'red', 'green', 'blue', 'orange'];
  String _color = '';


List<DropdownMenuItem<String>> getDropDownMenuItems() {
    List<DropdownMenuItem<String>> items = new List();
    for (String code in _countrycodes) {
      items.add(new DropdownMenuItem(
          value: code,
          child: new Text(code)
      ));
    }
    return items;
  }
  /**return new Material(
    color: Colors.blueAccent,
    child: new Scaffold(
    body: new Stack(
      children: <Widget>[
        new Container(
          decoration: new BoxDecoration(
            image: new DecorationImage(image: new AssetImage("assets/images/download.jpg"), fit: BoxFit.cover,),
          ),
        ),
        new Center(
          child: new Text("Hello LandingPage"),
        )
      ],
    )
  ));**/
final name = TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
initialValue: 'Techie Quickie',
decoration: InputDecoration(
  hintText: 'Name',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),
);

final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'tq@gmail.com',
decoration: InputDecoration(
  hintText: 'Email',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),

);

final password = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
  hintText: 'Password',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),

);

final passwordConfirmation = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
  hintText: 'Password',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),

);

final loginButton = Padding(
  padding: EdgeInsets.symmetric(vertical: 16.0),
  child: Material(
    borderRadius: BorderRadius.circular(30.0),
    shadowColor: Colors.lightBlueAccent.shade100,
    elevation: 5.0,
    child: MaterialButton(
      minWidth: 200.0,
      height: 42.0,
      onPressed: (){
        print("Signup button clicked");
      },
      color: Colors.lightBlueAccent,
      child: 
        Text('Sign Up', 
        style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
    ),
  )
);

final countryCode = DropdownButton(
  value: _selectedCountryCode,
  items: _dropDownMenuItems,
  onChanged: null
  );

  final inputDecoratoring =InputDecorator(
                    decoration: const InputDecoration(
                      icon: const Icon(Icons.color_lens),
                      labelText: 'Color',
                    ),
                    isEmpty: _color == '',
                    child: new DropdownButtonHideUnderline(
                      child: new DropdownButton<String>(
                        value: _color,
                        isDense: true,
                        onChanged: (String newValue) {
                          setState(() {
                            _color = newValue;
                          });
                        },
                        items: _colors.map((String value) {
                          return new DropdownMenuItem<String>(
                            value: value,
                            child: new Text(value),
                          );
                        }).toList(),
                      ),
                    ),
                  );





return Scaffold(
  backgroundColor: Colors.white,
  body: Center  (
    child: ListView(
      padding: EdgeInsets.only(left: 24.0, right: 24.0), 
      shrinkWrap: true,
      children: <Widget>[

        name,
        SizedBox(height: 18.0),
        email,
        SizedBox(height: 18.0),
        password,
        SizedBox(height: 18.0),
        passwordConfirmation,
        SizedBox(height: 18.0),
       // countryCode,
       // SizedBox(height: 18.0),
        loginButton,
        SizedBox(height: 38.0),
      ],
      )
      )

);

}

}

这是我的 main.dart 类

import 'package:flutter/material.dart';

import 'package:elegal_dart/screens/landing_page.dart';
import 'package:elegal_dart/screens/home.dart';
import 'package:elegal_dart/screens/devices.dart';
import 'package:elegal_dart/screens/signup.dart';
import 'package:elegal_dart/screens/signin.dart';

/*
void main()
{
  Devices( new MaterialApp(
    home: new Devices(),

  ));

}*/

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

class MyApp extends StatelessWidget
{
  @override
  Widget build(BuildContext context) 
  {
    return new MaterialApp(
      title: 'Navigation',
      routes: <String, WidgetBuilder>
      {
        '/Home' : (BuildContext context) => new Home(),
        '/LandingPage' : (BuildContext context) => new LandingPage(),
        '/Devices' : (BuildContext context) => new Devices(),
         '/Signup' : (BuildContext context) => new Signup(),
          '/Signin' : (BuildContext context) => new Signin(),

      },
      //home: new Signin(onSubmit: null),
      home: new Signup(),
      );
  }
}

更新代码:

import 'package:flutter/material.dart';



class Signup extends StatefulWidget{

  Signup({Key key}) : super (key:key);
  final String title;

  @override
  SignupPage createState() => new SignupPage();

}

class SignupPage extends State<Signup> {

@override
Widget build(BuildContext context) {
List _countrycodes = ["+65","+91"];
List<DropdownMenuItem<String>> _dropDownMenuItems;
String _selectedCountryCode;

List<String> _ccodes = <String>['', '+65', '+91', '+60', 'orange'];
  String _ccode = '';


List<DropdownMenuItem<String>> getDropDownMenuItems() {
    List<DropdownMenuItem<String>> items = new List();
    for (String code in _countrycodes) {
      items.add(new DropdownMenuItem(
          value: code,
          child: new Text(code)
      ));
    }
    return items;
  }

final name = TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
initialValue: 'Techie Quickie',
decoration: InputDecoration(
  hintText: 'Name',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),
);

final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'tq@gmail.com',
decoration: InputDecoration(
  hintText: 'Email',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),

  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),

);

final password = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
  hintText: 'Password',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),

);

final passwordConfirmation = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
  hintText: 'Password',
  contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
  border: OutlineInputBorder(

    borderRadius: BorderRadius.circular(32.0)
  ),

),

);

final loginButton = Padding(
  padding: EdgeInsets.symmetric(vertical: 16.0),
  child: Material(
    borderRadius: BorderRadius.circular(30.0),
    shadowColor: Colors.lightBlueAccent.shade100,
    elevation: 5.0,
    child: MaterialButton(
      minWidth: 200.0,
      height: 42.0,
      onPressed: (){
        print("Signup button clicked");
      },
      color: Colors.lightBlueAccent,
      child: 
        Text('Sign Up', 
        style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
    ),
  )
);

final countryCode = DropdownButtonHideUnderline (
  child:  DropdownButton<String>(
          value: _ccode,
          isDense: true,
          items: _ccodes.map((String value) {
                          return new DropdownMenuItem<String>(
                            value: value,
                            child: new Text(value),
                          );
                        }).toList(),
                  onChanged: (String newValue) {
                          setState(() {
                            _ccode = newValue;
                          });
                        }
  )
  );







return Scaffold(
  backgroundColor: Colors.white,
  body: Center  (
    child: ListView(
      padding: EdgeInsets.only(left: 24.0, right: 24.0), 
      shrinkWrap: true,
      children: <Widget>[

        name,
        SizedBox(height: 18.0),
        email,
        SizedBox(height: 18.0),
        password,
        SizedBox(height: 18.0),
        passwordConfirmation,
        SizedBox(height: 18.0),
        countryCode,
        SizedBox(height: 18.0),
        loginButton,
        SizedBox(height: 38.0),
      ],
      )
      )


);




}

}

我在 AVD 中遇到的错误

【问题讨论】:

    标签: dart flutter flutter-layout


    【解决方案1】:

    断言告诉你items 不能为空。它指的是这个:items: _dropDownMenuItems,。你永远不会分配_dropDownMenuItems

    这是 Dart-y 模式的一个很好的用途。替换为:

    final countryCode = DropdownButton(
      value: _selectedCountryCode,
      items: _countrycodes
          .map((code) =>
              new DropdownMenuItem(value: code, child: new Text(code)))
          .toList(),
      onChanged: null,
    );
    

    您不再需要该字段或getDropDownMenuItems 函数。如果您不熟悉此语法,请将其理解为“将 countryCodes 中的每个代码映射到 DropdownMenuItem 并将它们重新组合成 List”

    另外,你的变量的范围是错误的。将它们移出构建函数并进入状态,如下所示:

    class SignupPage extends State<Signup> {
      List<String> _countrycodes = ["+65", "+91"];
      List<String> _colors = ['', 'red', 'green', 'blue', 'orange'];
    
      String _selectedCountryCode;
      String _color = '';
    

    【讨论】:

    • 感谢这个,虽然我有一个想法并修改了代码,在上面更新了。但问题是我没有得到选定的值。
    • 您必须实现 onChanged 并将值存储在 setState 内的 _selectedCountryCode 中。
    • 请提供代码示例,我已经尝试过,但似乎不起作用。我最新的代码在原问题上面,tku 非常喜欢!
    【解决方案2】:

    我的回答也将解决在同一页面中使用多个 DropdownButton 的问题,而不会出现 DropdownMenuItem 中超过 1 个项目的错误。 首先定义您将以这种方式使用的列表:

    static const List<String> _razas = const
    ["Schnauzer", "Ovejero Alemán", "Husky", "Brasov", 
    "Constanta","Mestizo"];
    ////////barrios
    static const List<String> _barrios = const
    "Belgrano", "Caballito", "Colegiales", "Lugano", "Palermo","Pilar",  
    "Montserrat",  "Vicente López" ];
    static const List<String> _tamanio = const
    ["Chico", "Mediano", "Grande" ];
    
    String tamanioValue = _tamanio[0];
    String barriosValue = _barrios[0];
    String razasValue = _razas[0];
    

    然后在你的脚手架中使用这个容器

    Container(
                  margin: EdgeInsets.only(top:20.0, bottom: 20.0),
                  child: new Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                  children:<Widget> [
                    Text("RAZA      "),
                     new DropdownButton(value:razasValue,
                         onChanged: (string) => setState(() => razasValue = 
                         string),
                         items: _razas.map((string)  {
                                return new DropdownMenuItem(
                                child: new Text(string),
                                  value: string,
                                  );
                                  }).toList(),
                          ),
                          ]
                  )
                ),
    Container(
                margin: EdgeInsets.only(top:20.0, bottom: 20.0),
                     child: new Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children:<Widget> [
                          Text("BARRIO      "),
                          new DropdownButton(value:barriosValue,
                          onChanged: (string) => setState(() => 
                          barriosValue = string),
                          items: _barrios.map((string)  {
                          return new DropdownMenuItem(
                          child: new Text(string),
                          value: string,
                          );
                          }).toList(),
                          ),
                      ]
                     )
                ),
    

    然后只需替换您的数据库或存储数据的任何文件的值

    raza: razasValue,
    barrio: barriosValue,
    

    【讨论】:

      猜你喜欢
      • 2022-06-20
      • 2021-01-26
      • 2021-07-24
      • 1970-01-01
      • 2020-02-09
      • 1970-01-01
      • 2020-12-23
      • 2022-11-11
      • 2022-07-22
      相关资源
      最近更新 更多