Flutter - Dynamic suffix text for TextField?

自闭症网瘾萝莉.ら 提交于 2020-08-09 08:13:41

问题


I'm building a simple soundboard app in Flutter, which includes a search bar at the top of the application.

At the point where the search is activated, the interesting bit of the widget tree is as follows:

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

As text is typed into the search bar, a listener on the _filter updates a list of quotes which is used to build the body of the app. This is all working fine.

However, I would now like the app to show a count of the returned results, and since this is sitting in my header bar I'd like it to sit in-line with the bar itself, something like:

Things I've tried, all within the InputDecoration:

  • Setting suffixText - this is styled right and in the right place, however it doesn't update as the _filter changes because I'm not reconstructing the TextField every time (and I can't do this as it messes up what's been typed in).
  • Setting suffix to a full TextField widget with its own controller. This gets it auto-updating, but for some reason obscures my actual search text. I tried making the background transparent but that hasn't helped - new TextField(controller: _searchCountController, readOnly: true, textAlign: TextAlign.end, style: TextStyle(backgroundColor: Colors.transparent),). In the below screenshot, I've typed a 'w' which has updated the count to 84 (but I can't see the 'w' I've typed...)

  • Setting counter instead of suffix. I can get this to auto-update and not obscure my search, but it appears under the search bar which makes the whole thing look naff. Doesn't really seem appropriate for something sat in the title bar.

Any suggestions for how I can achieve what I'm after? Very new to Flutter so very possible that I've missed something obvious. Hoping there's a simple solution to this :)


回答1:


You can copy paste run full code below
You can use Row with Expanded(TextField) and Text()
code snippet

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'),
        ],
      ))

working demo

full code

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),
      ),
    );
  }
}



回答2:


Well, as expected it turned out I was missing something obvious and there was a simple solution. I was having trouble getting a simple suffixText to update because I was ultimately caching a component and therefore not giving Flutter a chance to re-render it.

In case it helps anyone, I had followed this post to implement a search bar. The pattern they use is to store an _appBarTitle widget which only gets changed when search is initiated and cancelled. I moved away from this approach, instead having a simple _searching boolean and allowing flutter to do the rest:

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');
    }
  }

With this approach, I don't need to specify a component for the suffix at all. It also has the advantage of automatically scooping up hintColor from my app's style.



来源:https://stackoverflow.com/questions/60138212/flutter-dynamic-suffix-text-for-textfield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!