Skip to content

Instantly share code, notes, and snippets.

@loicgeek
Created March 21, 2020 00:57
Show Gist options
  • Save loicgeek/903e2fe70d0daee3aefb6c42b3849cf3 to your computer and use it in GitHub Desktop.
Save loicgeek/903e2fe70d0daee3aefb6c42b3849cf3 to your computer and use it in GitHub Desktop.
This gist is a sample of Futurebuilder, search with highlighting
import 'package:flutter/material.dart';
import 'dart:core';
import 'dart:math';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Search Delegate example',
theme: ThemeData(
primaryColor: Colors.black,
),
//We are building our home according to how our app have started
home: HomePage());
}
}
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
String RandomString(int strlen) {
Random rnd = new Random(new DateTime.now().millisecondsSinceEpoch);
String result = "";
for (var i = 0; i < strlen; i++) {
result += chars[rnd.nextInt(chars.length)];
}
return result;
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future<List<Product>> productsFuture;
ProductRepository productRepo;
@override
initState(){
super.initState();
productRepo = new ProductRepository();
productsFuture = productRepo.fetchAll();
}
@override
Widget build(BuildContext context){
return Scaffold(
backgroundColor:Colors.white,
appBar:AppBar(
title:Text('Home'),
elevation:0,
centerTitle:true,
actions:[
IconButton(icon:Icon(Icons.search),onPressed:(){
showSearch(context:context,delegate:MySearchDelegate(productRepo:this.productRepo));
}),
]
),
body:MyFutureBuilder<List<Product>>(
future:productsFuture,
successWidget:(List<Product> products){
return ListView.separated(
itemCount:products.length,
separatorBuilder:(context,index){
return Divider(height:.1);
},
itemBuilder:(BuildContext context,int index){
Product p = products[index];
return Padding(
padding:EdgeInsets.symmetric(horizontal:8,vertical:1),
child:Container(
padding:EdgeInsets.all(8),
decoration:BoxDecoration(
color:Colors.grey.withOpacity(.2),),
child:Column(
children:[
Row(children:[
Text(' ${p.name}',style:TextStyle(fontWeight: FontWeight.w600)),
]),
Container(
child:Text('${p.description}',),),
]
),
),);
});
}));
}
}
class MySearchDelegate extends SearchDelegate{
ProductRepository productRepo;
MySearchDelegate({this.productRepo});
List<Widget> buildActions(BuildContext context){
return [
IconButton(
icon:Icon(Icons.cancel),
onPressed:(){
this.query = "";
}
),
];
}
Widget buildResults(BuildContext context){
if(query=='')return Container();
return MyFutureBuilder<List<Product>>(
future:this.productRepo.searchProducts(this.query),
successWidget:(List<Product> products){
return ListView.separated(
itemCount:products.length,
separatorBuilder:(context,index){
return Divider(height:.1);
},
itemBuilder:(BuildContext context,int index){
Product p = products[index];
return Padding(
padding:EdgeInsets.symmetric(horizontal:8,vertical:1),
child:Container(
padding:EdgeInsets.all(8),
decoration:BoxDecoration(
color:Colors.grey.withOpacity(.2),),
child:Column(
children:[
Row(children:[
Text(' ${p.name}',style:TextStyle(fontWeight: FontWeight.w600)),
]),
Container(
child:Text('${p.description}',),),
]
),
),);
});
}
);
}
buildLeading(BuildContext context){
return IconButton(
icon:Icon(Icons.arrow_back),
onPressed:(){
this.close(context,null);
}
);
}
buildSuggestions(BuildContext context){
if(query=='')return Container();
return MyFutureBuilder<List<Product>>(
future:this.productRepo.searchProducts(this.query),
successWidget:(List<Product> products){
return ListView.separated(
itemCount:products.length,
separatorBuilder:(context,index){
return Divider(height:.1);
},
itemBuilder:(BuildContext context,int index){
Product p = products[index];
return Padding(
padding:EdgeInsets.symmetric(horizontal:8,vertical:1),
child:Container(
padding:EdgeInsets.all(8),
decoration:BoxDecoration(
color:Colors.grey.withOpacity(.2),),
child:Column(
children:[
Row(children:[
buildMatch(query,p.name,context),
]),
Container(
child: buildMatch(query,p.description,context),),
]
),
),);
});
}
);
}
}
buildMatch(String query, String found,BuildContext context){
var tabs = found.toLowerCase().split(query.toLowerCase());
List<TextSpan> list=[];
for(var i =0;i<tabs.length;i++){
if(i%2==1){
list.add(TextSpan(text:query,style:TextStyle(color:Colors.green,fontWeight: FontWeight.w600,fontSize:15)));
}
list.add(TextSpan(text:tabs[i]));
}
return RichText(
text: TextSpan(
style:TextStyle(color:Colors.black),
children:list
),
);
}
//Common widget
class MyFutureBuilder<T> extends StatelessWidget{
final Future future;
Widget Function(dynamic error) errorWidget;
Widget Function(T data) successWidget;
MyFutureBuilder({
this.future,
this.errorWidget,
this.successWidget,
});
@override
build(BuildContext context){
return FutureBuilder<T>(
future:this.future,
builder:(BuildContext context,AsyncSnapshot snapshotData){
switch(snapshotData.connectionState){
case ConnectionState.active:
case ConnectionState.waiting:
return Center(child:Container(child:CircularProgressIndicator()));
case ConnectionState.none:
return Center(child:Text('Check Your Internet Connection'));
break;
case ConnectionState.done:
if(snapshotData.hasError){
return this.errorWidget!=null?this.errorWidget(snapshotData.error):Center(child:Text('${snapshotData.error}'));
}else{
return this.successWidget(snapshotData.data);
}
break;
default:
return Container();
}
});
}
}
// Repository file
class Product{
final int id;
final String name;
final String description;
final int price;
Product({this.id,this.name,this.description,this.price});
toString(){
return '''
$id: $name
''';
}
}
class ProductRepository {
final List<Product> products = List.generate(20,(int index){
return Product(id:index,name:"Product $index",description:RandomString(100),price:index*20);
});
Future<List<Product>> fetchAll(){
return Future.delayed(Duration(seconds:2),(){
return products;
});
}
Future<List<Product>> searchProducts(String query){
return Future.delayed(Duration(seconds:1),(){
return products.where((p){
return (p.name.toLowerCase().contains(query.toLowerCase()) || p.description.toLowerCase().contains(query.toLowerCase()));
}).toList();
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment