首页 > 解决方案 > 具有多个 TextField 和一个 DropDown 的行,其中一个 TextField 应该更大,并且都应该具有相同的高度

问题描述

我有一个包含 3 个字段的行:2 个文本字段,1 个 DropdownButtonHideUnderline 包装在容器中。我试图确保第一个 TextField 占用大约 50-60%,而其他两个字段共享剩余空间。我还希望这些字段具有相同的高度。所以,像这样:

在此处输入图像描述

这是我的代码:

  @override
  Widget build(BuildContext context) {
    return Container(
        color: Theme.of(context).accentColor,
        child: Padding(
            padding: const EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),
            child: Row(children: <Widget>[
              Expanded(
                  child: Container(
                      padding: EdgeInsets.only(right: 5.0),
                      child: TypeAheadField(
                        textFieldConfiguration: TextFieldConfiguration(
                            autofocus: true,
                            controller: widget.ingredientController,
                            style: DefaultTextStyle.of(context)
                                .style
                                .copyWith(fontStyle: FontStyle.italic),
                            decoration: InputDecoration(
                                border: InputBorder.none,
                                filled: true,
                                fillColor: Colors.white.withOpacity(1),
                                hintText: 'Ingredient',
                                suffixIcon: GestureDetector(
                                    onTap: widget.addFunction,
                                    child: Icon(
                                      Icons.add,
                                      color: Colors.grey,
                                    )))),
                        suggestionsCallback: (pattern) async {
                          return await _findIngredients(pattern);
                        },
                        //If not items are found, return an empty container.
                        noItemsFoundBuilder: (context) {
                          return Container(height: 0, width: 0);
                        },
                        itemBuilder: (context, suggestion) {
                          return ListTile(
                            title: Text(suggestion.name),
                          );
                        },
                        onSuggestionSelected: (Ingredient suggestion) {
                          widget.ingredientController.text = suggestion.name;
                        },
                      ))),
              Expanded(
                  child: TextField(
                      maxLines: 1,
                      controller: widget.quantityController,
                      keyboardType: TextInputType.text,
                      autofocus: false,
                      decoration: InputDecoration(
                        border: InputBorder.none,
                        filled: true,
                        fillColor: Colors.white.withOpacity(1),
                        hintText: 'Qty',
                      ))),
              Expanded(flex: 1, child: UnitDropdown()),
            ])));
  }

我剩下的是:

在此处输入图像描述

我尝试将 Expanded 上的 flex 因子设置为不同的东西,但这只会导致右侧溢出。我也没有找到强制所有小部件具有相同高度的方法。

标签: flutterflutter-layout

解决方案


在这里,关键是将 TextField、Dropdown 或您拥有的任何组件封装在 Container 中,并从 Container 中定义实际大小,调整每个小部件的预定义内部填充(如果有机会,有时不是可用的)。

 double itemsHeight = 30;

    Widget getTextField({String hint = 'Ingredients', Widget suffix}) {
        // use Container to define the size of the child, 
            // and reset the original inner paddings!
      return Container(
        height: itemsHeight,
        child: TextField(
          decoration: InputDecoration(
            border: OutlineInputBorder(
                borderRadius: BorderRadius.zero,
                borderSide: BorderSide(color: Colors.white, width: 1)),
            hintText: hint,
            contentPadding: EdgeInsets.all(
                0), // change each value, and set 0 remainding ones.
            suffixIcon: suffix,
          ),
          expands: false,
          maxLines: 1,
          controller: TextEditingController(),
        ),
      );
    }

    return Scaffold(
      body: Container(
        color: Colors.green.withOpacity(.2),
        margin: EdgeInsets.symmetric(vertical: 50, horizontal: 20),
        child: Row(
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            Flexible(
              flex: 2,
              child: getTextField(
                  hint: 'Ingredients',
                  suffix: Icon(
                    Icons.add,
                    size:
                        18, // option 1: reduce the size of the icon, and avoid the padding issues..
                  )),
            ),

            Flexible(
              flex: 1,
              child: getTextField(
                  hint: 'Qty',
                  // option2: trick to match the expanded height of the icon on the previous field
                  // make an icon transparent :)
                  suffix: Icon(
                    Icons.account_box,
                    color: Colors.transparent,
                  )),
            ),

            Flexible(
              flex: 1,
              child: Container(
                // use this to match the Flex size..., is like using Expanded.
                width: double.infinity,
                // container defines the BoxConstrains of the children
                decoration: BoxDecoration(
                  color: Colors.white24,
                  border: Border.all(color: Colors.white, width: 1),
                ),
                height: itemsHeight,
                child: DropdownButton(
                    hint: Text("Unit"),
                    onChanged: (i) {},
                    underline: Container(),
                    items: List.generate(5, (i) {
                      return DropdownMenuItem(child: Text("item $i"));
                    })),
              ),
            ),
          ],
        ),
      ),
    );

结果截图:

代码演示


推荐阅读