文本输入框(TextFormField)后缀图标出现问题

6
我有一个带有后缀图标的,它被用作。
TextFormField(
  autocorrect: false,
  decoration: InputDecoration(
    prefixIcon: widget.icon,
    isDense: true,
    suffixIcon: IconButton(
      icon: Icon(Icons.clear),
      onPressed: () {...}                 
    )
  ),     
  controller: _controller,
  maxLines: null,
)

我的问题是,后缀图标增加了文本字段的高度:

enter image description here

此外,文本末尾和图标之间的空间太大。

enter image description here

我尝试了不同的方法来避免这个问题,但几乎所有的方法都失败了。最后我在这里找到了一个可能的解决方案:https://github.com/flutter/flutter/issues/21908#issuecomment-516434465 所以,我尝试使用如下提到的 IntrinsicHeight widget:
IntrinsicHeight(
  child: TextFormField(...)
)

的确,它使我的TextFormField的高度规范化了,但现在出现了单词换行/断行的问题:

enter image description here

如您所见,多行调整不再正常工作,几乎无法确定何时会扩展。

那么:您有任何想法解决我的后缀图标问题和导致文本字段高度的初始问题吗?或者您知道如何在使用IntrisicHeight时修复多行问题吗?


你尝试过使用Inkwell或GestureDetector小部件代替IconButton吗? - Viren V Varasadiya
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
13

您可以复制下面的完整代码并运行。
步骤 1:您可以使用suffixIconConstraints来减少填充 https://github.com/flutter/flutter/pull/50058
步骤 2:使用InkWell包装Icon并设置Icon大小。

TextFormField(
                autocorrect: false,
                decoration: InputDecoration(
                    prefixIcon: Icon(Icons.add),
                    prefixIconConstraints: BoxConstraints(
                      minWidth: 5,
                      minHeight: 5,
                    ),
                    isDense: true,
                    suffixIconConstraints: BoxConstraints(
                      minWidth: 2,
                      minHeight: 2,
                    ),
                    suffixIcon: InkWell(
                        child: Icon(Icons.clear, size: 14), onTap: () {})),
                controller: _controller1,
                maxLines: null,
              ),

演示

在此输入图像描述

完整代码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  TextEditingController myController1 = TextEditingController();
  TextEditingController _controller1 = TextEditingController();
  TextEditingController _controller2 = TextEditingController();

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
              child: TextFormField(
                autocorrect: false,
                decoration: InputDecoration(
                    prefixIcon: Icon(Icons.add),
                    prefixIconConstraints: BoxConstraints(
                      minWidth: 5,
                      minHeight: 5,
                    ),
                    isDense: true,
                    suffixIconConstraints: BoxConstraints(
                      minWidth: 2,
                      minHeight: 2,
                    ),
                    suffixIcon: InkWell(
                        child: Icon(Icons.clear, size: 14), onTap: () {})),
                controller: _controller1,
                maxLines: null,
              ),
            ),
            Expanded(
              child: TextFormField(
                autocorrect: false,
                decoration: InputDecoration(
                    prefixIcon: Icon(Icons.add),
                    prefixIconConstraints: BoxConstraints(
                      minWidth: 5,
                      minHeight: 5,
                    ),
                    isDense: true,
                    suffixIconConstraints: BoxConstraints(
                      minWidth: 2,
                      minHeight: 2,
                    ),
                    suffixIcon: InkWell(
                        child: Icon(Icons.clear, size: 14), onTap: () {})),
                controller: _controller2,
                maxLines: null,
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

看起来不错!有两个问题:minWidth/minHeight 究竟是做什么的?我把它改成10或者null,都没有看到任何区别。第二个问题:是否可以在图标右侧添加一点空间?应该在 InkWell 内部使用 Container 吗? - S-Man
在源代码中,使用ConstrainedBox和BoxConstraints包装图标 https://github.com/flutter/flutter/blob/610dc170d95fadb5dff8f72022ca9dd528f45540/packages/flutter/lib/src/material/input_decorator.dart#L2243 - chunhunghan
作为拉取请求描述,当isDense设置为true时,这尤其有用,它允许图标尺寸小于48x48像素。 - chunhunghan
我使用填充来添加空间。你可以检查一下。suffixIcon: InkWell( child: Padding( padding: const EdgeInsets.only(right: 40), child: Icon(Icons.clear, size: 10), ), onTap: () {})) - chunhunghan
后缀导致对齐问题,suffixIcon 似乎可以解决我的问题。 - Ariel
看起来不错,我也查看了这个例子 - http://techandroidhub.com/prefix-and-suffix-icon-in-textfield/ - Sawan Modi

0
decoration: InputDecoration(
                                    errorBorder: OutlineInputBorder(
                                        borderSide: const BorderSide(
                                            color: Colors.red),
                                        borderRadius:
                                            const BorderRadius.all(
                                                Radius.circular(10))),
                                    labelText: "Current password",

//将IconButton更改为GestureDetector

                                    suffixIcon:     GestureDetector(
                                      onTap: () {
                                        controller.isObscureOld.value =
                                        !controller.isObscureOld.value;
                                      },
                                      child: Icon(
                                        !controller.isObscureOld.value
                                            ? Icons.visibility_outlined
                                            : Icons.visibility_off_outlined,
                                        size: 26,
                                        color: ColorConstants.grayLight,
                                      ),
                                    ),
                                  ),

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,