You can copy paste run full code below
You can filter searchQuery
in ShowList
code snippet
TextField(
decoration: InputDecoration(
hintText: "Country Search",
suffixIcon: Icon(Icons.search),
),
controller: _searchQueryController,
onChanged: (value) {
searchQuery = value;
setState(() {});
},
)
...
const ShowList({Key key, this.search}) : super(key: key);
@override
Widget build(BuildContext context) {
var detail = search
.where(
(s) => s.country.toLowerCase().contains(searchQuery.toLowerCase()))
.toList();
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount: detail.length,
itemBuilder: (BuildContext context, int index) {
Search s = detail[index];
working demo
full code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
List<Search> searchFromJson(String str) =>
List<Search>.from(json.decode(str).map((x) => Search.fromJson(x)));
String searchToJson(List<Search> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Search {
Search({
this.country,
this.continent,
this.code,
});
String country;
String continent;
String code;
factory Search.fromJson(Map<String, dynamic> json) => Search(
country: json["country"],
continent: json["continent"],
code: json["code"],
);
Map<String, dynamic> toJson() => {
"country": country,
"continent": continentValues.reverse[continent],
"code": code,
};
}
enum Continent { NORTH_AMERICA, EUROPE }
final continentValues = EnumValues(
{"Europe": Continent.EUROPE, "North America": Continent.NORTH_AMERICA});
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
class SearchPage extends StatefulWidget {
@override
_SearchPageState createState() => _SearchPageState();
}
String searchQuery = "";
class _SearchPageState extends State<SearchPage> {
List<String> _tabs = ['North America', 'Europe'];
TextEditingController _searchQueryController = TextEditingController();
bool _isSearching = false;
Future<List<Search>> _future;
@override
void initState() {
_future = SearchServices.getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: _tabs.length,
child: Scaffold(
appBar: AppBar(
title: TextField(
decoration: InputDecoration(
hintText: "Country Search",
suffixIcon: Icon(Icons.search),
),
controller: _searchQueryController,
onChanged: (value) {
searchQuery = value;
setState(() {});
},
),
bottom: TabBar(
tabs: _tabs.map((String name) => Tab(child: Text(name))).toList(),
),
),
body: FutureBuilder(
future: _future,
builder: (BuildContext context, AsyncSnapshot snapshot) {
List<Widget> children;
List<Search> _search = snapshot.data;
if (snapshot.hasData) {
return TabBarView(
children: _tabs.map((String name) {
return ShowList(
search: List<Search>.from(_search)
..retainWhere((e) => e.continent == name));
}).toList(),
);
} else {
children = <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60),
const Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading...'))
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children));
}),
),
);
}
}
class ShowList extends StatelessWidget {
final List<Search> search;
const ShowList({Key key, this.search}) : super(key: key);
@override
Widget build(BuildContext context) {
var detail = search
.where(
(s) => s.country.toLowerCase().contains(searchQuery.toLowerCase()))
.toList();
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount: detail.length,
itemBuilder: (BuildContext context, int index) {
Search s = detail[index];
return Card(
child: Column(children: [
Text(s.country),
Image.network('https://www.countryflags.io/${s.code}/flat/64.png'),
]),
);
},
);
}
}
class SearchServices {
static const String url =
'https://firebasestorage.googleapis.com/v0/b/tft-test-48c87.appspot.com/o/search.json?alt=media&token=08236daf-cc72-4c3b-b052-7822f8790b12';
static Future<List<Search>> getData() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final List<Search> data = searchFromJson(response.body);
return data;
} else {
return List<Search>();
}
} catch (e) {
return List<Search>();
}
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SearchPage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}