问题
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 theTextField
every time (and I can't do this as it messes up what's been typed in). - Setting
suffix
to a fullTextField
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 ofsuffix
. 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