在我的移动应用程序主页上,我有两个选项卡作为类别。这两个选项卡都显示一个列表视图,其内容取决于类别。(例如,包含小说和非小说类别的图书列表。)我想添加一个搜索功能来搜索一本书,而不管它们的类别如何。
问题是:
我认为的解决办法:
就是添加setState,这样每当我点击搜索栏时,选项卡就不会移动回默认选项卡,但是我不知道怎么做。
这是我的代码:
// Tab Bar MOF and CIDB
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16)
),
color: Theme.of(context).primaryColor,
),
width: double.infinity,
child: TabBar(
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
indicatorPadding: EdgeInsets.all(6),
indicator: const UnderlineTabIndicator(borderSide: BorderSide(color: Colors.red, width: 100.0),
insets: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 42.0),
),
unselectedLabelColor: Colors.grey,
tabs: [
Tab(child: Text('MOF', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w300, ))),
Tab(child: Text('CIDB', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w300)))
]
),
),
SizedBox(
height: 30,
),
//Space for Tender Listview
Expanded(
child: Container(
width: double.infinity,
//Tender List tile
child: TabBarView(
controller: _tabController,
children: [
//MOF List
Column(
children: [
Expanded(
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: MOFs.length,
itemBuilder: (context, index) {
final MOF = MOFs[index];
return Card(
margin: EdgeInsets.fromLTRB(15, 20, 15, 20),
child: InkWell(
onTap: (){},
child: Container(
margin: EdgeInsets.all(4),
height: 200,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12),
//color: Colors.blue
),
child: Center(child: Text(MOF.title)),
),
),
);
}),
),
Container(
//color: Colors.pink,
margin: EdgeInsets.fromLTRB(150, 10, 150, 10),
child: TextField(
controller: controller,
onChanged: searchMOF,
decoration: InputDecoration(
hintText: 'Search by Keyword',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(color: Colors.green))
),
),
),
],
),
//CIDB List
Column(
children: [
Expanded(
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: CIDBs.length,
itemBuilder: (context, index) {
final CIDB = CIDBs[index];
return Container(
margin: EdgeInsets.all(10),
height: 200,
width: 50,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20),
//color: Colors.purple
),
child: InkWell(
onTap: (){},
child: Card
(child: Center(child: Text(CIDB.title))),
),
//List testing
);
}),
),
Container(
//color: Colors.pink,
margin: EdgeInsets.fromLTRB(150, 10, 150, 10),
child: TextField(
controller: controller,
onChanged: searchCIDB,
decoration: InputDecoration(
hintText: 'Search by Keyword',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(color: Colors.green))
),
),
),
],
),
],
),
),
),
],
),
);
}发布于 2022-10-05 10:56:23
通过创建带有搜索栏的父有状态小部件和带有选项卡和选项卡主体的子小部件,可以使搜索栏全局工作。在每个选项卡主体中,您可以检查搜索文本字段控制器是否为空,如果是,则只显示包含搜索文本的书籍,如果没有,则显示整个列表。
发布于 2022-10-06 01:53:16
整个步骤太宽了。我建议一些提纲。
ListView在颤振:创造与毁灭中的行为只有可见的子元素将在列表视图中呈现。当子对象被滚动出视图时,相关的元素子树、状态和呈现对象将被销毁。
setState时,它意味着颤振、重新执行build方法。下面的方法。 @override
Widget build(BuildContext context) {
return这就是为什么,每次调用setState时,选项卡都返回到第一个选项卡。因为它从一开始就执行build方法。
class TabMOF extend StatelessWidget{
...
@override
Widget build(BuildContext context) {
return your MOF list
...class TabCIBD extend StatelessWidget{
...
@override
Widget build(BuildContext context) {
return your CIBD list然后在主屏幕中使用is作为小部件。
...
body : Column(
children: [
// here will be your search bar
...
// next is your tabbar
Container(
child: TabBar(
tabs: [tab1, tab2 ]
)
Expanded(
child: TabBarView(
children:[
TabMOF(),
TabCIBD(),
]
]这样,您的选项卡就不会重建。但是您必须更新每个选项卡的列表数据。如果需要重新生成stateFullwidget选项卡,可以更改值键。文章
其实很难解释得很详细,希望你明白我的意思。谢谢
https://stackoverflow.com/questions/73958622
复制相似问题