如何修复“ BoxConstraints强制无限宽度”,以及如何从列表中删除项目?

时间:2019-05-26 10:08:14

标签: flutter

我是Flutter的初学者,但由于遇到“布局问题”,所以无法获得所需的结果。我试了好几个小时了...


技术问题:
当我单击“添加播放器按钮”以添加新的TextField来设置更多播放名称时,出现错误:“ BoxConstraints强制无限宽度”。因此,不会显示TextField。


enter image description here

我不知道如何实现的其他功能:
-我有一个“下拉菜单”来选择难度游戏。为什么不显示默认文字(难度:正常)?
-如何执行此操作:当用户单击“删除”图标(请参见TextField上的suffixIcon)时,是否删除了相应的fieldText?
-如何执行:当用户单击添加播放器时,默认的HintText会递增(播放器2,播放器3,播放器4 ....)? -为什么用户滚动页面时我的背景渐变无法固定? (就像HTML / CSS的“背景附件:固定”一样)?

import 'package:flutter/material.dart';

/// Styles

///




class Homepage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyHomePageState();
  }
}


class _MyHomePageState extends State<Homepage> {

  String dropdownValue = 'Normal';

  List<TextField> _playerList = new List(); //_playerList is my List name
  int playerListIndex = 0; //Count the number of times "Add" button clicked

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      body: Stack(children: <Widget>[
        // To have a gradient background
        new Container(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          decoration: new BoxDecoration(
            gradient: new LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              stops: [0.1, 1],
              colors: [
                Colors.redAccent[200],
                Colors.red[300],
              ],
              tileMode:
                  TileMode.repeated,
            ),
          ),

          //I need SingleChildScrollView to haven't "Overflow yellow bar on bottom screen"
          child: SingleChildScrollView(

            child: Container(

              padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  mainAxisSize: MainAxisSize.min,

                  children: <Widget>[
                    // Box to add big image
                    SizedBox(
                      height: 450,
                    ),



                    // DROP DOWN MENU to choose difficulty  modes
                    InputDecorator(
                      decoration: InputDecoration(
                        prefixIcon: const Icon(Icons.games),
                        filled: true,
                      ),
                      child: DropdownButtonHideUnderline(
                        child: new DropdownButton<String>(
                          value: dropdownValue,
                          hint: Text('Difficulty normal'),
                          isDense: true,
                          items: <String>['Normal', 'Easy', 'Hard']
                              .map<DropdownMenuItem<String>>((String value) {
                            return DropdownMenuItem<String>(
                              value: value,
                              child: Text(value),
                            );
                          }).toList(),
                          onChanged: (String newValue) {
                            setState(() {
                              dropdownValue = newValue;
                            });
                          },
                        ),
                      ),
                    ),

                    //Field player name 1. At least I need 1 player
                        new TextField(
                          maxLength: 20,
                          decoration: InputDecoration(
                            prefixIcon: const Icon(Icons.person),
                            filled: true,
                            hintText:"Player 1",
                            counterText: "",
                          ),
                        ),


                    //Field for other player name 2, 3, 4, ...
                    new ListView.builder(
                      padding: EdgeInsets.all(0),
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemCount: _playerList.length,
                      itemBuilder: (context, index) {
                        TextField widget = _playerList.elementAt(index);
                        return widget;
                      }),

                    //Button to add other field text to set player name. The user can delete a player on click on "clear icon button"
                    new Align(
                      alignment: Alignment.centerRight,
                      child: FlatButton.icon(
                          color: Colors.black,
                          icon: Icon(
                            Icons.add,
                            color: Colors.white,
                            size: 18,
                          ),
                          label: Text('Add player',
                              style:
                                  TextStyle(fontSize: 12, color: Colors.white)),
                          onPressed: () {
                            setState(() {
                              playerListIndex++;
                              _playerList.add(
                                    new TextField(
                                      maxLength: 20,
                                      decoration: InputDecoration(
                                        prefixIcon: const Icon(Icons.person),
                                        suffixIcon: new IconButton(
                                            icon: Icon(Icons.clear),
                                            onPressed: () {
                                              _playerList.removeAt(playerListIndex); //Doesn't work
                                            }),
                                        filled: true,
                                        hintText: "Player $playerListIndex", //Doesn't work i would like Player 2, Player 3, ...
                                        counterText: "",
                                      ),
                                    ),
                              );
                              print(playerListIndex);
                              print(_playerList);
                              print(_playerList[0]);
                            });
                          }),
                    ),
                    new ButtonTheme(
                      minWidth: 350,
                      height: 45,
                      child: FlatButton(
                        color: Colors.black,
                        child: Text('Play',
                            style:
                                TextStyle(fontSize: 18, color: Colors.white)),
                        onPressed: () {
                          // Perform some action
                        },
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ]),
    );
  }


}

1 个答案:

答案 0 :(得分:0)

我认为我了解发生了什么事。让我们开始吧:

首先。您的TextField未显示,并且由于未设置宽度和高度而收到错误消息,因此,它正在尝试获得最大尺寸。解决方案呢?将其包装在Container小部件(或SizedBox)中,并为其指定宽度和高度。那应该解决第一个问题。

第二。由于您没有在DropDown小部件See the hint propierty below中传递参数“提示”,因此未显示DropDownMenu的提示文本(难度正常)。

第三。您想在单击后缀时清除TextField字符串,对吗?为此,请将GestureDetectorIconButton作为后缀组件,创建一个TextEditingController并将其传递到控制器部分的TextField中,然后在onPressed / onTap方法(取决于要设置的窗口小部件)对此进行设置: _textController.text.clear() 方法,位于 setState函数中。这应该可以解决问题。

第四。您是否希望随着添加更多玩家而增加玩家的字符串列表?您有多种方法可以实现此目的,其中一种方法是创建一个空列表,可以进行模拟测试,然后,每次单击“添加播放器”按钮时,都会在for中添加与该值对应的String循环在“ Player $ index”中将for的索引作为int值传递。再次,for方法将收到一个setState方法,在setState内,您的逻辑将再添加一个Player。

最后,您的渐变不固定吗?嗯,我想您可以在名为resizeToAvoidBottomInset的Scaffold小部件中传递属性并将其设置为false。

如果某些操作没有按照您的预期工作,请回复它,我会为您提供帮助。