I have created a page in which there is search bar and then the listview builder which is building items of List coming from provider class. When I tap on search bar, the keyboard appears ,suddenly disappears and page refreshes. when page is refreshed, first it shows circularprogressIndicator and then regular ListView.builder.
Kindly Help.
Thank you in advance!
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();
}
this is the function which searches the items and updates the list
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,
),
)
]),
),
);
}
}
this widget builds the item of 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)
],
)
],
)
],
),
),
);
}