Reputation: 123
i am a beginner of flutter programming. i got a problem for search feature of listview when i use future builder, when i type a letter it change the list for a second, but back to all list data after a second. i dont know what's the error, because there is no warning or errors only. i stack on this code, please helpppppppppppppppp......
this is my code, Default list data when i type letters, the list back again after a seconds
List mydata;
List unfilterData;
Future loadJsonData() async {
List data = json.decode(await rootBundle.loadString('Json/indomodel.json'));
setState(() {
mydata = data;
this.unfilterData = mydata;
});
return data;
}
Widget mylist() {
return FutureBuilder(
future: loadJsonData(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.amber),
));
else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, index) {
return Card(
elevation: 0.3,
child: ListTile(
// leading: CircleAvatar(child: Icon(FontAwesomeIcons.adjust),),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SelectableText(
mydata[index]['word'],
// data[index]['word'],
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.deepPurple.shade800),
),
Text(
"My Kamus",
style: TextStyle(color: Colors.grey, fontSize: 10),
)
],
),
SizedBox(
height: 10.0,
),
Text(
mydata[index]['trans'],
style: TextStyle(
color: Colors.grey.shade700, fontSize: 13.0),
)
],
),
),
);
},
);
}
},
);
}
searchData(str) {
var strExist = str.length > 0 ? true : false;
if (strExist) {
var filterData = [];
for (var i = 0; i < unfilterData.length; i++) {
String word = unfilterData[i]['word'];
if (word.contains(str)) {
filterData.add(unfilterData[i]);
}
}
setState(() {
this.mydata = filterData;
});
} else {
setState(() {
//
this.mydata = this.unfilterData;
});
}
}
Upvotes: 2
Views: 7748
Reputation: 10963
The problem in your code is that you are calling loadJsonData()
in the FutureBuilder
, so when you call setState()
the loadJsonData()
will be called again.
What you should do is to call loadJsonData()
once, in the initState()
, save the future into a variable and use that variable on the FutureBuilder
, like this:
Future _future;
@override
void initState() {
super.initState();
_future = loadJsonData();
}
And in the FutureBuilder
do this:
future: _future,
Note: since you need to filter the list it's okay to save the list to mydata
and then use mydata
in the ListView.builder()
, just make sure to change this part to avoid confusion:
itemCount: snapshot.data.length,
should be:
itemCount: mydata.length,
Suggestions:
Future
and List
so you can access to the properties without warnings, in your case
would be like this: Future<List<Map<String, dynamic>>>
and
List<Map<String, dynamic>>
.setState()
from a future because the widget
could be disposed and cause errors, you could set the list inside the
FutureBuilder
.Upvotes: 18