我在TabBar中有一个带有2个选项卡的页面,如下所示:
class SearchByCityOrPerson extends StatefulWidget {
SearchByCityOrPerson({Key key, this.title}) : super(key: key);
final String title;
@override
_SearchByCityOrPerson createState() => _SearchByCityOrPerson();
}
class _SearchByCityOrPerson extends State<SearchByCityOrPerson> {
List<String> _cities = ['Albania', 'Andorra', 'Armenia', 'Austria',
'Azerbaijan', 'Belarus', 'Belgium', 'Bosnia and Herzegovina', 'Bulgaria',
'Croatia', 'Cyprus', 'Czech Republic', 'Denmark', 'Estonia', 'Finland',
'France', 'Georgia', 'Germany', 'Greece', 'Hungary', 'Iceland', 'Ireland',
'Italy', 'Kazakhstan', 'Kosovo', 'Latvia', 'Liechtenstein', 'Lithuania',
'Luxembourg', 'Macedonia', 'Malta', 'Moldova', 'Monaco', 'Montenegro',
'Netherlands', 'Norway', 'Poland', 'Portugal', 'Romania', 'Russia',
'San Marino', 'Serbia', 'Slovakia', 'Slovenia', 'Spain', 'Sweden',
'Switzerland', 'Turkey', 'Ukraine', 'United Kingdom', 'Vatican City'];
List<String> _persons = ["John Smith", "Alex Johnson", "Jane Doe", "Eric Johnson", "Michael Eastwood", "Benjamin Woods"];
List<String> _filteredList = [];
TextEditingController controller = new TextEditingController();
String filter = "";
Icon actionIcon = new Icon(Icons.search);
Widget appBarTitle = new Text("Search...");
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
void initState() {
setState(() {
_filteredList = _cities;
});
controller.addListener(() {
if (controller.text.isEmpty) {
setState(() {
filter = "";
_filteredList = _cities;
});
} else {
setState(() {
filter = controller.text;
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
ListTile personListTile(String bookOrPerson) =>
ListTile(
title: Text(
bookOrPerson,
style: TextStyle(
color: Colors.black45, fontWeight: FontWeight.bold),
),);
Card personCard(bookOrPeson) =>
Card(
child: Container(
decoration: BoxDecoration(color: Colors.grey[300]),
child: personListTile(bookOrPeson),
),
);
if ((filter.isNotEmpty)) {
List<String> tmpList = new List<String>();
for (int i = 0; i < _filteredList.length; i++) {
if (_filteredList[i].toLowerCase().contains(
filter.toLowerCase())) {
tmpList.add(_filteredList[i]);
}
}
_filteredList = tmpList;
}
final appBody = Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _cities == null ? 0 : _filteredList.length,
itemBuilder: (BuildContext context, int index) {
return personCard(_filteredList[index]);
},
),
);
final appTopAppBar = AppBar(
elevation: 0.1,
bottom: TabBar(
tabs: [
GestureDetector(
child: Text("City"),
onTap: (){
_filteredList = _cities;
},
),
GestureDetector(
child: Text("Person"),
onTap: (){
_filteredList = _persons;
},
),
]
),
title: appBarTitle,
actions: <Widget>[
new IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close);
this.appBarTitle = new TextField(
controller: controller,
decoration: new InputDecoration(
/*prefixIcon: new Icon(Icons.search, color: Colors.white),*/
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white),
),
style: new TextStyle(
color: Colors.white,
),
autofocus: true,
cursorColor: Colors.white,
);
} else {
this.actionIcon = new Icon(Icons.search);
this.appBarTitle = new Text("Cities");
_filteredList = _cities;
controller.clear();
}
});
},
),
],
);
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: appTopAppBar,
body: appBody,
),
);
}
}
您可能已经在屏幕快照中看到过,问题在于secon选项卡的“按人搜索”选项被制表了,它应该显示所有人的列表,并允许用户按人名进行搜索,但我试图做到这一点在每个选项卡的on选项卡方法中,但是需要以某种方式进行刷新,我想有一种更好的方法来实现它,考虑到列表__ cities和 _ persons将在以后进行api调用时加载。
经过一个小时我在这里做的事情
- [在正文中添加了TabBar视图,以在第二个选项卡中显示人员列表。
- 老实说,对于搜索,我什么也没做..我只是添加了您所做的相同代码,但添加了人员列表。
- 我删除了DefaultTabController并为索引添加了控制器,以便为不同的TabBar获得不同的标题。
这里是代码
class SearchByCityOrPerson extends StatefulWidget {
SearchByCityOrPerson({Key key, this.title}) : super(key: key);
final String title;
@override
_SearchByCityOrPerson createState() => _SearchByCityOrPerson();
}
class _SearchByCityOrPerson extends State<SearchByCityOrPerson> with SingleTickerProviderStateMixin {
List<String> _cities = ['Albania', 'Andorra', 'Armenia', 'Austria',
'Azerbaijan', 'Belarus', 'Belgium', 'Bosnia and Herzegovina', 'Bulgaria',
'Croatia', 'Cyprus', 'Czech Republic', 'Denmark', 'Estonia', 'Finland',
'France', 'Georgia', 'Germany', 'Greece', 'Hungary', 'Iceland', 'Ireland',
'Italy', 'Kazakhstan', 'Kosovo', 'Latvia', 'Liechtenstein', 'Lithuania',
'Luxembourg', 'Macedonia', 'Malta', 'Moldova', 'Monaco', 'Montenegro',
'Netherlands', 'Norway', 'Poland', 'Portugal', 'Romania', 'Russia',
'San Marino', 'Serbia', 'Slovakia', 'Slovenia', 'Spain', 'Sweden',
'Switzerland', 'Turkey', 'Ukraine', 'United Kingdom', 'Vatican City'];
List<String> _persons = ["John Smith", "Alex Johnson", "Jane Doe", "Eric Johnson", "Michael Eastwood", "Benjamin Woods"];
List<String> _filteredList = [];
List<String> _personsList = [];
TextEditingController controller = new TextEditingController();
TabController _tabController;
String filter = "";
String persons = "";
Icon actionIcon = new Icon(Icons.search);
Widget appBarTitle = new Text("Search...");
void _handleTabIndex() {
setState(() {});
}
@override
void dispose() {
controller.dispose();
_tabController.removeListener(_handleTabIndex);
_tabController.dispose();
super.dispose();
}
@override
void initState() {
_tabController = TabController(length: 2, vsync: this, initialIndex: 0);
_tabController.addListener(_handleTabIndex);
setState(() {
_filteredList = _cities;
_personsList = _persons;
});
controller.addListener(() {
if (controller.text.isEmpty) {
setState(() {
filter = "";
persons = "";
_filteredList = _cities;
_personsList = _persons;
});
} else {
setState(() {
filter = controller.text;
persons = controller.text;
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
ListTile personListTile(String bookOrPerson) =>
ListTile(
title: Text(
bookOrPerson,
style: TextStyle(
color: Colors.black45, fontWeight: FontWeight.bold),
),);
Card personCard(bookOrPerson) => Card(
child: Container(
decoration: BoxDecoration(color: Colors.grey[300]),
child: personListTile(bookOrPerson),
),
);
if ((filter.isNotEmpty)) {
List<String> tmpList = new List<String>();
for (int i = 0; i < _filteredList.length; i++) {
if (_filteredList[i].toLowerCase().contains(
filter.toLowerCase())) {
tmpList.add(_filteredList[i]);
}
}
_filteredList = tmpList;
}
if ((persons.isNotEmpty)) {
List<String> _tmpList2 = new List<String>();
for (int i = 0; i < _personsList.length; i++) {
if (_personsList[i].toLowerCase().contains(
persons.toLowerCase())) {
_tmpList2.add(_personsList[i]);
}
}
_personsList = _tmpList2;
}
final appBody = TabBarView(
controller: _tabController,
children: [
Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _cities == null ? 0 : _filteredList.length,
itemBuilder: (BuildContext context, int index) {
return personCard(_filteredList[index]);
},
),
),
Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _persons == null ? 0 : _personsList.length,
itemBuilder: (BuildContext context, int index) {
return personCard(_personsList[index]);
},
),
),
]);
final appTopAppBar = AppBar(
elevation: 0.1,
bottom: TabBar(
controller: _tabController,
tabs: [
Tab( text: "City"),
Tab(text: "person")
]
),
title: appBarTitle,
actions: <Widget>[
new IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close);
this.appBarTitle = new TextField(
controller: controller,
decoration: new InputDecoration(
/*prefixIcon: new Icon(Icons.search, color: Colors.white),*/
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white),
),
style: new TextStyle(
color: Colors.white,
),
autofocus: true,
cursorColor: Colors.white,
);
} else {
this.actionIcon = new Icon(Icons.search);
this.appBarTitle = new Text(_tabController.index == 0 ? "Cities" : "Persons");
_filteredList = _cities;
_personsList = _persons;
controller.clear();
}
});
},
),
],
);
return
Scaffold(
appBar: appTopAppBar,
body: appBody,
);
}
}