我创建了一个页面,其中有搜索栏,然后是列表视图构建器,该构建器正在构建来自提供程序类的列表项目。当我点击搜索栏时,键盘出现,突然消失并且页面刷新。刷新页面时,首先显示circularprogressIndicator,然后常规显示ListView.builder。\n请帮助。\n预先感谢您!
import 'package:carstraders/models/cars.dart';\nimport 'package:carstraders/providers/cars_provider.dart';\nimport 'package:flutter/foundation.dart';\nimport 'package:flutter/material.dart';\nimport 'package:provider/provider.dart';\n\nclass SearchPage extends StatefulWidget {\n static const routeName = 'search-page';\n\n const SearchPage({Key? key}) : super(key: key);\n\n @override\n _SearchPageState createState() => _SearchPageState();\n}\n\nclass _SearchPageState extends State<SearchPage> {\n var search = TextEditingController();\n var list = [];\n List<Cars> allItems = [];\n String query = '';\n\n bool isFirstTime = true;\n\n @override\n void initState() {\n allItems = Provider.of<CarsProvider>(context, listen: false).list;\n list = allItems;\n // TODO: implement initState\n super.initState();\n }\nRun Code Online (Sandbox Code Playgroud)\n这是搜索项目并更新列表的功能
\n void searchItem(String val) {\n final searched = allItems.where((element) {\n final transmission = element.transmission.toLowerCase();\n final model = element.model.toLowerCase();\n final make = element.make.toLowerCase();\n final price = element.price.toString();\n final engine = element.engine.toString();\n final searchedVal = val.toLowerCase();\n if (model.contains(searchedVal) ||\n make.contains(searchedVal) ||\n price.contains(searchedVal) ||\n engine.contains(searchedVal) ||\n transmission.contains(searchedVal)) {\n return true;\n }\n return false;\n }).toList();\n setState(() {\n list = searched;\n query = val;\n });\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: const Text('Search'),\n ),\n body: FutureBuilder(\n future: Provider.of<CarsProvider>(context,listen: false).fetchAndSet(),\n builder: (ctx, snap) => snap.connectionState == ConnectionState.waiting\n ? const Center(\n child: CircularProgressIndicator(),\n )\n : Column(children: [\n Row(\n children: [\n Expanded(\n child: Padding(\n padding: const EdgeInsets.all(8.0),\n child: TextField(\n onChanged: searchItem,\n // style: TextStyle(color: Colors.white),\n controller: search,\n key: const Key('search'),\n keyboardType: TextInputType.emailAddress,\n decoration: InputDecoration(\n label: const Text('Search'),\n suffixIcon: query.isEmpty\n ? null\n : GestureDetector(\n child: const Icon(Icons.close),\n onTap: () {\n setState(() {\n query = '';\n searchItem('');\n search.clear();\n FocusScope.of(context).unfocus();\n });\n },\n ),\n prefixIcon: const Icon(Icons.search_sharp),\n enabledBorder: const OutlineInputBorder(\n borderSide: BorderSide(\n color: Colors.grey,\n width: 0.5,\n ),\n ),\n ),\n ),\n ),\n ),\n ],\n ),\n Expanded(\n child: ListView.builder(\n itemBuilder: (ctx, i) => buildItem(list[i], context),\n itemCount: list.length,\n ),\n )\n ]),\n ),\n );\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n这个小部件构建了以下项目listview.builder
Widget buildItem(Cars item, BuildContext context) {\n return GestureDetector(\n onTap: () =>\n Navigator.of(context).pushNamed('search-item-detail', arguments: item),\n child: Card(\n elevation: 5,\n child: Row(\n // mainAxisAlignment: MainAxisAlignment.start,\n children: [\n SizedBox(\n width: MediaQuery.of(context).size.width * 0.43,\n child: Image.network(item.img),\n ),\n SizedBox(width: MediaQuery.of(context).size.width * 0.02),\n Column(\n children: [\n Text(\n item.year.toString() + ' ' + item.make + ' ' + item.model,\n style: const TextStyle(\n color: Colors.blueAccent,\n ),\n ),\n SizedBox(\n width: MediaQuery.of(context).size.width * 0.5,\n child: const Divider(color: Colors.black)),\n Row(\n children: [\n Text('${item.mileage} mi'),\n Container(\n margin: EdgeInsets.symmetric(\n horizontal: MediaQuery.of(context).size.width * 0.03),\n decoration: const BoxDecoration(\n border: Border(left: BorderSide(color: Colors.grey))),\n child: const Text('')),\n Text('\xc2\xa3${item.price}')\n ],\n ),\n SizedBox(\n width: MediaQuery.of(context).size.width * 0.5,\n child: const Divider(color: Colors.black)),\n Row(\n children: [\n Text(' ' + item.plateNo),\n Container(\n margin: EdgeInsets.symmetric(\n horizontal: MediaQuery.of(context).size.width * 0.03),\n child: const Text(''),\n decoration: const BoxDecoration(\n border: Border(left: BorderSide(color: Colors.grey))),\n ),\n Text(item.transmission)\n ],\n )\n ],\n )\n ],\n ),\n ),\n );\n}\nRun Code Online (Sandbox Code Playgroud)\n
未来的构建器会在每次构建时触发。因此,当您单击searchBox键盘时,会更改屏幕尺寸并Expanded重建futureBuilder。
替换未来 Builder 的以下部分
Column
row
Expanded
listView.Builder
Run Code Online (Sandbox Code Playgroud)
和
ListView.builder(
itemBuilder: (ctx, i) {
if(i==0){
return row
}
return buildItem(list[i -1], context)
},
itemCount: list.length + 1,
),
Run Code Online (Sandbox Code Playgroud)
我认为你的代码可以写得更好。如果您使用 bloc 模式或 Riverpod 模式(类似于提供程序并且具有相同的作者),请查看此链接
| 归档时间: |
|
| 查看次数: |
1039 次 |
| 最近记录: |