Flutter:如何在输入修饰中将提示文本旁边的图标居中?

2hh7jdfx  于 2023-01-27  发布在  Flutter
关注(0)|答案(3)|浏览(228)

Example of desired effect
我有一个TextField和一个InputDecoration,其中我设置了一个hintText和一个prefixIcon,但是我使用的prefixIcon属性总是将图标一直拉到左边。

TextField(
  textAlign: TextAlign.center,
  decoration: InputDecoration(
    contentPadding: EdgeInsets.fromLTRB(0, 30, 0, 30),
    prefixIcon: Icon(Icons.search),
    hintText: 'Search',
    fillColor: Color(0xffF1F4FB),
    filled: true,
    enabledBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(25),
      borderSide: BorderSide(
        color: Color(0xffF1F4FB),
      ),
    ),
    disabledBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(25),
      borderSide: BorderSide(
        color: Color(0xffF1F4FB),
      ),
    ),
  ),
),

我正在尝试更改这个设置,使搜索图标和提示文本一开始就相互居中。我该如何实现这个效果?

doinxwow

doinxwow1#

下面是一个使用IntrinsicWidth的解决方案。
使用此解决方案,搜索图标将位于hinttext旁边,然后它将停留在用户输入的文本旁边。

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          height: 48.0,
          padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 0.0),
          margin: EdgeInsets.all(8.0),
          decoration: BoxDecoration(
            color: Colors.amber.shade300,
            border: Border.all(
              color: Colors.brown,
              width: 3.0,
            ),
            borderRadius: BorderRadius.circular(25),
          ),
          child: Center(
            child: IntrinsicWidth(
              child: TextField(
                textAlignVertical: TextAlignVertical.center,
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.search),
                  hintText: 'Search',
                  border: InputBorder.none,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
q5iwbnjs

q5iwbnjs2#

prefixIcon设置为www.example.com中的Row就可以了。但是它覆盖了整个textField,所以当textField处于焦点位置时,我们需要将其替换为普通图标。MainAxisAlignment.center could do the trick.butit covers the whole textField, so we need to replace it with a normal icon when the textField is in focus.
您可以使用FocusNode检测焦点。要了解更多信息,请阅读Focus and text fields
代码:

class MyTextField extends StatefulWidget {
  const MyTextField({Key key}) : super(key: key);

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

class _MyTextFieldState extends State<MyTextField> {
  TextEditingController _controller = TextEditingController();
  FocusNode _focusNode = FocusNode();

  @override
  void initState() {
    // rebuild the textfield on focus changes
    _focusNode.addListener(() {
      setState(() {});
    });
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _controller,
      focusNode: _focusNode,
      textAlign: TextAlign.center,
      decoration: InputDecoration(
        contentPadding: EdgeInsets.fromLTRB(0, 30, 0, 30),
        prefixIcon: !_focusNode.hasFocus && _controller.text.isEmpty
            ? Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Icon(Icons.search),
                  Text('Search'),
                ],
              )
            : Icon(Icons.search),
        // hintText: 'Search',
        fillColor: Color(0xffF1F4FB),
        filled: true,
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(25),
          borderSide: BorderSide(
            color: Color(0xffF1F4FB),
          ),
        ),
        disabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(25),
          borderSide: BorderSide(
            color: Color(0xffF1F4FB),
          ),
        ),
      ),
    );
  }
}
xlpyo6sf

xlpyo6sf3#

我使用prefixIconConstraints来实现这一点。只需使用prefixIcon将其添加到TextFormField的装饰中,如下所示:

prefixIconConstraints: const BoxConstraints(),
prefixIcon: Container(
   margin: EdgeInsets.symmetric(horizontal: 12),
   child: const Text('Rp'),
),

你还应该想通过在TextFormField的修饰中添加一些填充来使你的字段看起来更大:

contentPadding: EdgeInsets.all(8),

相关问题