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
:
- 设置
suffixText
- 这是正确的样式和正确的位置,但是它不会随着 _filter
的变化而更新,因为我不是每次都重建 TextField
(我不能这样做,因为它会弄乱输入的内容)。
- 将
suffix
设置为具有自己控制器的完整 TextField
小部件。这得到它 auto-updating,但由于某种原因模糊了我的实际搜索文本。我尝试使背景透明,但这没有帮助 - new TextField(controller: _searchCountController, readOnly: true, textAlign: TextAlign.end, style: TextStyle(backgroundColor: Colors.transparent),)
。在下面的屏幕截图中,我输入了一个 'w',它已将计数更新为 84(但我看不到我输入的 'w'...)
- 设置
counter
而不是 suffix
。我可以将它发送到 auto-update 而不会混淆我的搜索,但它出现在搜索栏下方,这让整个事情看起来很糟糕。似乎真的不适合标题栏中的内容。
关于我如何实现我所追求的目标有什么建议吗?对 Flutter 非常陌生,所以很可能我错过了一些明显的东西。希望有一个简单的解决方案:)
您可以复制粘贴 运行 下面的完整代码
您可以将 Row
与 Expanded(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
的优势。
我正在 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
:
- 设置
suffixText
- 这是正确的样式和正确的位置,但是它不会随着_filter
的变化而更新,因为我不是每次都重建TextField
(我不能这样做,因为它会弄乱输入的内容)。 - 将
suffix
设置为具有自己控制器的完整TextField
小部件。这得到它 auto-updating,但由于某种原因模糊了我的实际搜索文本。我尝试使背景透明,但这没有帮助 -new TextField(controller: _searchCountController, readOnly: true, textAlign: TextAlign.end, style: TextStyle(backgroundColor: Colors.transparent),)
。在下面的屏幕截图中,我输入了一个 'w',它已将计数更新为 84(但我看不到我输入的 'w'...)
- 设置
counter
而不是suffix
。我可以将它发送到 auto-update 而不会混淆我的搜索,但它出现在搜索栏下方,这让整个事情看起来很糟糕。似乎真的不适合标题栏中的内容。
关于我如何实现我所追求的目标有什么建议吗?对 Flutter 非常陌生,所以很可能我错过了一些明显的东西。希望有一个简单的解决方案:)
您可以复制粘贴 运行 下面的完整代码
您可以将 Row
与 Expanded(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
的优势。