Flutter - TextField 的动态后缀文本?

Flutter - Dynamic suffix text for TextField?

我正在 Flutter 中构建一个简单的音板应用程序,其中包括应用程序顶部的搜索栏。

在激活搜索的地方,widget tree 的有趣部分如下:

home: Scaffold(
          appBar: AppBar(
            title: new TextField(
              controller: _filter,
              decoration: new InputDecoration(
                prefixIcon: new Icon(Icons.search, color: Colors.white),
                hintText: 'Search...'
          ),

在搜索栏中输入文本时,_filter 上的侦听器会更新用于构建应用程序 body 的引号列表。一切正常。

但是,我现在希望该应用程序显示返回结果的计数,并且由于它位于我的 header 栏中,所以我希望它与栏一起 in-line本身,类似于:

我尝试过的东西,都在 InputDecoration:

关于我如何实现我所追求的目标有什么建议吗?对 Flutter 非常陌生,所以很可能我错过了一些明显的东西。希望有一个简单的解决方案:)

您可以复制粘贴 运行 下面的完整代码
您可以将 RowExpanded(TextField)Text()
一起使用 代码片段

AppBar(
          title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Expanded(
            child: TextField(
                controller: _filter,
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.search, color: Colors.white),
                  hintText: 'Search...',
                )),
          ),
          Text('$_counter'),
        ],
      ))

工作演示

完整代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      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 _filter = TextEditingController();
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Expanded(
            child: TextField(
                controller: _filter,
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.search, color: Colors.white),
                  hintText: 'Search...',
                )),
          ),
          Text('$_counter'),
        ],
      )),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

好吧,正如预期的那样,我遗漏了一些明显的东西,并且有一个简单的解决方案。我在更新一个简单的 suffixText 时遇到了麻烦,因为我最终缓存了一个组件,因此没有给 Flutter 重新渲染它的机会。

为了帮助大家,我已经按照 this post 实现了一个搜索栏。他们使用的模式是存储一个 _appBarTitle 小部件,该小部件仅在搜索启动和取消时发生变化。我放弃了这种方法,而是使用一个简单的 _searching 布尔值并让 flutter 完成剩下的工作:

Widget _buildAppBar() {
    if (_searching) {
      return new TextField(
          controller: _filter,
          decoration: new InputDecoration(
            prefixIcon: new Icon(Icons.search, color: Colors.white),
            hintText: 'Search...',
            suffixText: '${_filteredQuotes.length}',
          ),
          autofocus: true,
          style: TextStyle(color: Colors.white));
    } else {
      return new Text('Pocket Scat');
    }
  }

使用这种方法,我根本不需要为后缀指定组件。它还具有从我的应用程序样式中自动获取 hintColor 的优势。