Keyboard Suddenly Disappears Of TextField
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)
],
)
],
)
],
),
),
);
}
Answer
future builder trigger on every build. so when you click on searchBox
the keyboard changes screen size and Expanded
rebuild futureBuilder
.
Solution Easy way .
Replace below part of future Builder
Column
row
Expanded
listView.Builder
with
ListView.builder(
itemBuilder: (ctx, i) {
if(i==0){
return row
}
return buildItem(list[i -1], context)
},
itemCount: list.length + 1,
),
I think your code can write better. if you use bloc pattern or Riverpod pattern(similar to provider and has same author) so please look at this links
Related Questions
- → How do you create a 12 or 24 mnemonics code for multiple cryptocurrencies (ETH, BTC and so on..)
- → Flutter: input text field don't work properly in a simple example..... where am I wrong?
- → Can I customize the code formatting of Dart code in Atom?
- → Is it possible to develop iOS apps with Flutter on a Linux virtual machine?
- → Display SnackBar in Flutter
- → JSON ObjectMapper in Flutter
- → Material flutter app source code
- → TabBarSelection No such method error
- → How do I set the animation color of a LinearProgressIndicator?
- → Add different routes/screens to Flutter app
- → Is there a way to get the size of an existing widget?
- → How to share a file using flutter
- → Is there an easy way to find particular text built from RichText in a Flutter test?