【发布时间】:2022-01-12 09:54:30
【问题描述】:
我创建了一个页面,其中有搜索栏,然后是 listview 构建器,它正在构建来自提供程序类的 List 项目。当我点击搜索栏时,键盘出现,突然消失并刷新页面。刷新页面时,首先显示circularprogressIndicator,然后显示常规ListView.builder。
请帮助。
提前谢谢!
import 'package:carstraders/models/cars.dart';
import 'package:carstraders/providers/cars_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class SearchPage extends StatefulWidget {
static const routeName = 'search-page';
const SearchPage({Key? key}) : super(key: key);
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
var search = TextEditingController();
var list = [];
List<Cars> allItems = [];
String query = '';
bool isFirstTime = true;
@override
void initState() {
allItems = Provider.of<CarsProvider>(context, listen: false).list;
list = allItems;
// TODO: implement initState
super.initState();
}
这是搜索项目并更新列表的功能
void searchItem(String val) {
final searched = allItems.where((element) {
final transmission = element.transmission.toLowerCase();
final model = element.model.toLowerCase();
final make = element.make.toLowerCase();
final price = element.price.toString();
final engine = element.engine.toString();
final searchedVal = val.toLowerCase();
if (model.contains(searchedVal) ||
make.contains(searchedVal) ||
price.contains(searchedVal) ||
engine.contains(searchedVal) ||
transmission.contains(searchedVal)) {
return true;
}
return false;
}).toList();
setState(() {
list = searched;
query = val;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Search'),
),
body: FutureBuilder(
future: Provider.of<CarsProvider>(context,listen: false).fetchAndSet(),
builder: (ctx, snap) => snap.connectionState == ConnectionState.waiting
? const Center(
child: CircularProgressIndicator(),
)
: Column(children: [
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: searchItem,
// style: TextStyle(color: Colors.white),
controller: search,
key: const Key('search'),
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
label: const Text('Search'),
suffixIcon: query.isEmpty
? null
: GestureDetector(
child: const Icon(Icons.close),
onTap: () {
setState(() {
query = '';
searchItem('');
search.clear();
FocusScope.of(context).unfocus();
});
},
),
prefixIcon: const Icon(Icons.search_sharp),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey,
width: 0.5,
),
),
),
),
),
),
],
),
Expanded(
child: ListView.builder(
itemBuilder: (ctx, i) => buildItem(list[i], context),
itemCount: list.length,
),
)
]),
),
);
}
}
此小部件构建listview.builder 的项目
Widget buildItem(Cars item, BuildContext context) {
return GestureDetector(
onTap: () =>
Navigator.of(context).pushNamed('search-item-detail', arguments: item),
child: Card(
elevation: 5,
child: Row(
// mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.43,
child: Image.network(item.img),
),
SizedBox(width: MediaQuery.of(context).size.width * 0.02),
Column(
children: [
Text(
item.year.toString() + ' ' + item.make + ' ' + item.model,
style: const TextStyle(
color: Colors.blueAccent,
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: const Divider(color: Colors.black)),
Row(
children: [
Text('${item.mileage} mi'),
Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.03),
decoration: const BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))),
child: const Text('')),
Text('£${item.price}')
],
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: const Divider(color: Colors.black)),
Row(
children: [
Text(' ' + item.plateNo),
Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.03),
child: const Text(''),
decoration: const BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))),
),
Text(item.transmission)
],
)
],
)
],
),
),
);
}
【问题讨论】:
-
附带说明,您应该调用 super.initState();在 initState 的开头。
-
你为什么使用futurebuilder?您可以简单地使用带有搜索小部件 + Expanded(ListView.builder) 的列。 Check this video!
-
FutureBuilder 在从提供者列表中获取数据时显示加载微调器。如果需要改进,请告诉我。我会非常感谢你。
-
@FlutterBeginner
fetchAndSet究竟做了什么?请也发布该代码。 -
问题解决了。我刚刚删除了futurebuilder