I make small app to display listview and then I want can search data into this list view. Now the List is working but the problem into TextField of search. When I click inside TextField the list reload agin and the user out of TextField removed again.
See this image please to understand more the problem:
As you can see in the image above I can't write data inside TextField.
This is first page I pass list data from this page to second page from FutureBuilder:
class firstPage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<firstPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kBackground,
body: Center(
child: Column(
children: [
Expanded(
child: FutureBuilder<List<AllProductModel>>(
future: fetchYourProduct(Uids, NameUserContry),
builder: (context, snapshot) {
final ListDataDisplay = snapshot.data;
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
if (snapshot.hasError) {
return Center(
child: Text('Some error occurred!'));
} else {
return UserPage(ListDataDisplay:ListDataDisplay);
}
}
},
),
)
],
))
);
}
}
This is second page user page here I display data and I make appBar here also:
class UserPage extends StatefulWidget {
final ListDataDisplay;
UserPage({Key? key, required this.ListDataDisplay}) : super(key: key);
@override
State<UserPage> createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
TextEditingController editingController = TextEditingController();
Widget appBarTitle = Text('');
Icon actionIcon = Icon(
Icons.search,
color: CustomColors.firebaseNavy,
);
String searchString = "";
TextEditingController searchController = TextEditingController();
@override
Widget build(BuildContext context) =>
Scaffold(
appBar: AppBar(
centerTitle: true,
title:appBarTitle,
backgroundColor: CustomColors.firebaseGrey,
elevation: 1.5,
actions: <Widget>[
IconButton(onPressed: (){
setState(() {
if ( this.actionIcon.icon == Icons.search){
this.actionIcon = Icon(Icons.close);
this.appBarTitle = TextField(
onChanged: (value) {
setState((){
searchString = value;
});
},
controller: searchController,
style: TextStyle(
color: Colors.black,
),
decoration: InputDecoration(
labelText: 'Name',
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black),
),
),
);
}
else {
this.actionIcon = Icon(Icons.search);
this.appBarTitle = Text("List");
searchController.clear();
searchString='';
}
}
);
},icon: actionIcon,
)
,]
),
body:
ListView.builder(
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: widget.ListDataDisplay.length,
itemBuilder: (context, index) {
return
"${widget.ListDataDisplay[index]
.name}" ':' "${widget.ListDataDisplay[index].coponId}"
.contains(searchString) ?
Card(
elevation: 1.5,
child: Container(
padding: EdgeInsets.all(6),
child: Row(
children: <Widget>[
Text(widget.ListDataDisplay[index].name)
],
),
),
) : Container();
}
)
);
}
How I can solve this problem?
CodePudding user response:
to avoid unecessary reloads for the Future
, move it into initState so it will load the data once and stored in a variable, then assign that variable to the future property in FutureBuilder like this :
late Future someNameHere;
@override
void initState(){
someNameHere = fetchYourProduct(Uids, NameUserContry);
super.initState();
}
then in your FutureBuilder
assign it to future property like :
future: someNameHere;
Hope it helps