How To implement appbar Search with provider api in flutter - flutter

I'm getting all the users from API and showing it on a list view. what I need to do is when I search for a specific username, then it needs to show a list tile of users that match the same name .after that when I click that username in the search list view I need to show the user profile of that user which I need user-id
I already used showSearch(context: context, delegate: CustomSearchDelegate());
and I fail
this is my UserList Api Class
class GetSharedPatientList with ChangeNotifier {
Future<List<Content>> fetchPatientList(
BuildContext context,
) async {
final bool isConnected = await InternetConnectionChecker().hasConnection;
final prefs = await SharedPreferences.getInstance();
var uuid = prefs.getString("userId");
final bool session = await Session.sessionValid(context);
if (isConnected) {
if (session) {
try {
final response =
await http.get(Uri.parse('$baseUrl/profile_shares?uuid=$uuid'));
if (response.statusCode == 200) {
List jsonResponse = json.decode(response.body)['content'];
print(jsonResponse);
return jsonResponse.map((data) => Content.fromJson(data)).toList();
} else {
throw Exception('Unexpected error occured!');
}
} catch (e) {
Logger().e(e);
}
} else {}
} else {
Alert(
context: context,
type: AlertType.error,
title: "No Internet",
desc: "Please Check Your Internet Connection",
buttons: [
DialogButton(
onPressed: () => Navigator.pop(context),
color: green,
child: const Text(
"Ok",
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
]).show();
}
throw Exception('Failed to load user');
}
}
CustomSearchDelegate Class
class CustomSearchDelegate extends SearchDelegate {
getList(BuildContext context) async {
List<Content> data = await Provider.of<GetSharedPatientList>(context)
.fetchPatientList(context);
return data;
}
// first overwrite to
// clear the search text
#override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
onPressed: () {
query = '';
},
icon: const Icon(Icons.clear),
),
];
}
// second overwrite to pop out of search menu
#override
Widget? buildLeading(BuildContext context) {
return IconButton(
onPressed: () {
close(context, null);
},
icon: const Icon(Icons.arrow_back),
);
}
// third overwrite to show query result
#override
Widget buildResults(BuildContext context) {
List<Content> matchQuery = getList(context);
for (var pateint in matchQuery) {
if (pateint.recipientName!.contains(query.toLowerCase())) {
matchQuery.add(pateint);
}
}
return ListView.builder(
itemCount: matchQuery.length,
itemBuilder: (context, index) {
return ProfileList(
patientid: matchQuery[index].senderId.toString(),
username: matchQuery[index].senderName.toString(),
phn: matchQuery[index].phn.toString(),
sharedDate: matchQuery[index].sharedDate.toString(),
);
},
);
}
// last overwrite to show the
// querying process at the runtime
#override
Widget buildSuggestions(BuildContext context) {
List<Content> matchQuery = getList(context);
for (var pateint in matchQuery) {
if (pateint.recipientName!.toLowerCase().contains(query.toLowerCase())) {
matchQuery.add(pateint);
}
}
return ListView.builder(
itemCount: matchQuery.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
UtilFunctions.navigateTo(context,
MainScreen(patientid: matchQuery[index].senderId.toString()));
},
child: ProfileList(
patientid: matchQuery[index].senderId.toString(),
username: matchQuery[index].senderName.toString(),
phn: matchQuery[index].phn.toString(),
sharedDate: matchQuery[index].sharedDate.toString(),
));
},
);
}
}
When I run this I'm getting _TypeError (type 'Future<dynamic>' is not a subtype of type 'List<Content>')
Any Help is much appreciated

Related

StateError (Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist)

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:mumu/utils/navigator/exports.dart';
import 'group_tile.dart';
class ChatsList extends StatefulWidget {
const ChatsList({Key? key}) : super(key: key);
#override
State<ChatsList> createState() => _ChatsListState();
}
class _ChatsListState extends State<ChatsList> {
String groupName = "";
String username = "";
String email = "";
Stream? groups;
bool isLoading = false;
User? user = FirebaseAuth.instance.currentUser;
#override
void initState() {
gettingUserDetails();
super.initState();
}
String getGroupId(String res) {
return res.substring(0, res.indexOf("_"));
}
String getGroupName(String res) {
return res.substring(res.indexOf("_") + 1);
}
gettingUserDetails() async {
final userDetails = await FirebaseFirestore.instance
.collection("users")
.doc(user?.uid)
.get();
await userDetails.data()?["username"].then((value) {
setState(() {
username = value;
});
});
await userDetails.data()?["email_id"].then((value) {
setState(() {
email = value;
});
});
// setState(() {
// widget.username = username;
// widget.email = email;
// });
//getting the list of snapshots in our stream
final userSnapshot = FirebaseFirestore.instance
.collection("users")
.doc(user?.uid)
.snapshots();
setState(() {
groups = userSnapshot;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: groupList(),
floatingActionButton: FloatingActionButton(
onPressed: () {
popUpDialog(context);
},
child: Icon(Icons.add),
),
);
}
createGroup(String username, String id, String groupName) async {
DocumentReference groupDocumentReference =
await FirebaseFirestore.instance.collection("groups").add({
"groupName": groupName,
"groupIcon": "",
"admin": "${id}_$username",
"members": [],
"groupId": "",
"recentMessage": "",
"recentMessageSender": "",
});
//updating the members
await groupDocumentReference.update({
"members": FieldValue.arrayUnion(["${user?.uid}_$username"]),
"groupId": groupDocumentReference.id,
});
//updating groups in users collection
DocumentReference userDocumentReference =
FirebaseFirestore.instance.collection("users").doc(user?.uid);
return await userDocumentReference.update({
"groups":
FieldValue.arrayUnion(["${groupDocumentReference.id}_$groupName"]),
});
}
popUpDialog(BuildContext context) {
showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: const Text(
'Create a group',
textAlign: TextAlign.left,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
isLoading == true
? const Center(
child: CircularProgressIndicator(),
)
: TextField(
onChanged: (value) {
setState(() {
groupName = value;
});
},
decoration: InputDecoration(labelText: "Chat name"),
)
],
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("Cancel")),
ElevatedButton(
onPressed: () async {
if (groupName != null) {
setState(() {
isLoading = true;
});
}
createGroup(username,
FirebaseAuth.instance.currentUser!.uid, groupName);
isLoading = false;
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Group created successfully"),
backgroundColor: Colors.green,
));
},
child: Text("Create"))
],
);
},
);
},
);
}
groupList() {
return StreamBuilder(
stream: groups,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData &&
snapshot.data['groups'] != null && //<-- Here is shows the bad state error
snapshot.data["groups"].length != 0) {
return ListView.builder(
itemCount: snapshot.data["groups"].length,
itemBuilder: (BuildContext context, int index) {
int reverseIndex = snapshot.data["groups"].length - index - 1;
return GroupTile(
username: snapshot.data["username"],
groupId: getGroupId(snapshot.data["groups"][reverseIndex]),
groupName: getGroupName(snapshot.data["groups"][reverseIndex]),
);
},
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Text("no messages");
}
},
);
}
}
Here is my cloud_firestore collection:
I was making a group chat app and got an error StateError (Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist) . Here I was taking snapshot from the users collection and storing that in the "groups" stream. and then I was using the stream in the StreamBuilder of groupsList() method. Here it can't access the users collection from the firebase. Please help me guys.

Riverpood does not update the status until I enter the screen

I have a general configuration screen, with a button that syncs the data
(...)
appBar: AppBar(
actions: [
Row(
children: [
const Text(ConfigurationsStringsUI.updateGeneral),
IconButton(
icon: const Icon(Icons.sync),
onPressed: () {
ref.read(listProductController.notifier).syncProducts();
ref.read(listEmployedController.notifier).syncEmployees();
},
),
],
)
],
),
(...)
In the case of products, it has a specific screen that is responsible for managing them, basically a CRUD. When I press the sync button, the idea is to connect to supabase and update the data. While this is happening display a loadign. The problem is that the loading does not appear.
products_page.dart
GetIt sl = GetIt.instance;
class CRUDProduct extends ConsumerWidget {
#override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop();
},
),
actions: [
IconButton(
onPressed: () {
ref.read(listProductController.notifier).syncProducts();
},
icon: const Icon(Icons.update),
)
],
),
floatingActionButton: ref.watch(isVisibleFabProducts)
? FloatingActionButton(
onPressed: () {
showDialog(
context: scaffoldKey.currentContext!,
builder: (context) => AddProductDialog(),
);
},
child: const Icon(Icons.fastfood),
)
: null,
body: ref.watch(listProductController).when(
data: (products) {
if (products.isEmpty) {
return const Center(
child: Text(ProductStringsUI.emptyList),
);
} else {
return NotificationListener<UserScrollNotification>(
onNotification: (notification) {
if (notification.direction == ScrollDirection.forward) {
ref.read(isVisibleFabProducts.notifier).state = true;
}
if (notification.direction == ScrollDirection.reverse) {
ref.read(isVisibleFabProducts.notifier).state = false;
}
return true;
},
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) {
return ItemProductList(product: products[index]);
},
separatorBuilder: (_, __) => const Divider(
color: Colors.grey,
),
itemCount: products.length),
);
}
},
error: (error, stackTrace) {
return const Center(
child: Text(ProductStringsUI.errorList),
);
},
loading: () {
return const Center(child: CircularProgressIndicator());
},
));
}
}
Product provider:
final listProductController =
StateNotifierProvider<ProductController, AsyncValue<List<LocalProduct>>>(
(ref) => ProductController(ref));
product_controller.dart
class ProductController extends StateNotifier<AsyncValue<List<LocalProduct>>> {
ProductController(this._ref) : super(const AsyncValue.loading()) {
getProducts();
}
final Ref _ref;
Future<void> getProducts() async {
try {
final employees = await sl.get<ListProductUseCase>().getProducts();
if (mounted) {
state = AsyncValue.data(employees);
}
} catch (e) {
state = AsyncValue.error(e, StackTrace.current);
}
}
Future<void> syncProducts() async {
try {
_ref.read(listCategoryController.notifier).state =
const AsyncValue.loading();
_ref.read(listEmployedController.notifier).state =
const AsyncValue.loading();
state = const AsyncValue.loading();
await _ref.read(listCategoryController.notifier).syncCategory();
final employees = await sl.get<SyncProductUseCase>().syncProducts();
state.whenData((value) {
if (mounted) {
state = AsyncValue.data([...value, ...employees]);
}
});
_ref.invalidate(listProductController);
} catch (e) {
state = AsyncValue.error(e, StackTrace.current);
}
}
}
In the case of products, it has a specific screen that is responsible for managing them, basically a CRUD. When I press the sync button, the idea is to connect to supabase and update the data. While this is happening display a loadign. The problem is that the loading does not appear. There are two scenarios:
1-I open the app, I press the sync button on the configuration screen, I enter the screen in charge of managing the products, I see the loaded products, and at the moment it updates me with the new data, when I should see the loading and then the new ones data.
In this scenario is where my biggest doubt about the strange behavior is.
2-I open the app, I enter the screen in charge of managing the products, I go to the configuration screen, I press sync, and in that case if I go to enter if the loading appears
The same goes for employees.
When you have an async provider in Riverpod, you should tell it to load:
Future<void> addTopic(String name) async {
state = const AsyncValue.loading(); // Here
state = await AsyncValue.guard(() async { // And then you guard the value
// Inside the brackets do all the logic of the function
final currentId = ref.watch(currentSubjectProvider);
final topicRepo = ref.watch(topicRepoProvider);
await topicRepo.addTopic(currentId!, name);
return _getTopics();
});
}
This example of mine, is a real project I am working on, and this is loading as expected, but I should mention that I am using the Riverpod generator, so if the generator did something, I am unaware of it.
If you set the state to loading and guard the value, all listerners of that provider should be loading correctly.

how to remove duplicate from list of objects in flutter?

I'm new to flutter. I'm working on small projects which is like a scanning QR app. Here, I used hive to store scanned data in box but the problem is, it is storing duplicate values.
I need to remove that duplicate data how to do it?
code:
class PageState extends State<PassthroughQrScanPage> {
final ApiRepository repository = ApiRepository(
apiClient: ApiClient(
httpClient: http.Client(),
),
);
#override
void initState() {
super.initState();
openBox();
Prefs().reload();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
create: (context) => PassthroughqrscanBloc(repository),
child: BlocConsumer<PassthroughqrscanBloc, PassthroughqrscanState>(
listener: (context, state) {
if (state is PassthroughqrscanEmpty) {
return scan(context);
}
if (state is PassthroughqrscanError) {
Navigator.pop(context);
ShowErrorMessage(context, state.error.message.toString());
}
if (state is PassthroughqrscanLoaded) {
List<Batch> cleared = [];
state.entity.batches.forEach((element) {
cleared.add(element);
});
// final clearedData =
// cleared.map((item) => jsonEncode(item)).toList();
// final uniqueJsonList = clearedData.toSet().toList();
// List result =
// uniqueJsonList.map((item) => jsonDecode(item)).toList();
var seen = Set<int>();
List<Batch> clearedData = cleared
.where((cleared) => seen.add(cleared.batchNumber!))
.toList();
// clearedData = [
// ...{...clearedData}
// ];
clearedData.forEach((element) {
debugPrint(
"check the values for all the sdasd ${element.batchNumber}");
box.add(Batch(
batchNumber: element.batchNumber,
isUsed: element.isUsed,
transactionId: element.transactionId));
});
print("adding ssssss ${box.values.toList()}");
// String json = jsonEncode(state.entity);
// print("------>>>>>>>>>>>D>S>D>>$json");
// Prefs().setPassthroughData(json);
Navigator.pop(context);
WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog(
context: context,
builder: (ctxDialog) => PassDialog(
compoundCode: widget.compoundCode.toString(),
lotNo: widget.lotNo.toString(),
schedule_id: widget.schedule_id.toString(),
screenClosed: _screenWasClosed,
scheduleRange: widget.scheduleRange,
batchQty: widget.batchQty,
));
});
}
// return Container();
Center(
child: CircularProgressIndicator(),
);
},
builder: (context, state) {
if (state is PassthroughqrscanEmpty) {
return scan(context);
} else
return scan(context);
},
),
),
);
}
scan(BuildContext mcontext) =>
MobileScanner(
controller: MobileScannerController(facing: CameraFacing.back),
allowDuplicates: false,
onDetect: (barcode, args) {
if (barcode.rawValue == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Scan correct QR"),
duration: Duration(milliseconds: 800)));
});
} else {
String code = barcode.rawValue ?? "";
debugPrint('Barcode found! $code');
if (code.isNotEmpty) {
// if (!_screenOpened) {
// _screenOpened = true;
passthroughData = jsonDecode(code);
passthroughQrScan =
PassthroughQrScanData.fromJson(passthroughData);
BlocProvider.of<PassthroughqrscanBloc>(mcontext)
..add(VerifyPassthroughBatch(
passthroughQrScan?.operationName ?? "",
widget.schedule_id.toString(),
passthroughQrScan?.transactionId ?? "",
passthroughQrScan?.transactionRange ?? ""));
buildShowDialog(context);
}
}
});
Widget ShowErrorMessage(BuildContext context, String error) {
print("------------------------------/./././$error");
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Scan correct QR"),
duration: Duration(milliseconds: 800)));
});
return scan(context);
}
Future<void> openBox() async {
box = await Hive.openBox<Batch>("GetBatches");
// box = Boxes.getAllBatches();
await box.clear();
debugPrint("wwwwwwwwwwwwwwwwwkekekkkkkkkkk${box.values}");
// await box.deleteAll(box.keys);
}
}
List<Batch> batched = [];
var data;
class PassDialog extends StatefulWidget {
// const PassDialog({Key? key}) : super(key: key);
String? schedule_id;
String? compoundCode;
String? lotNo;
final Function() screenClosed;
final String? scheduleRange;
final int? batchQty;
PassDialog(
{required this.schedule_id,
required this.compoundCode,
required this.lotNo,
required this.screenClosed,
required this.scheduleRange,
required this.batchQty});
#override
State<PassDialog> createState() => _PassDialogState();
}
class _PassDialogState extends State<PassDialog> {
#override
void initState() {
batched = box.values.toSet().toList();
print("got values check for $batched");
super.initState();
}
#override
Widget build(BuildContext context) {
// List<Batch> batch = box.get("GetBatches");
//Batch batch = box?.get("GetBatches");
return SizedBox(
width: 150,
height: 100,
child: AlertDialog(
content: SingleChildScrollView(
child: Column(
children: [
// batched.forEach((element) {
for (final q in batched)
Text(
'${q.batchNumber.toString()}--${q.isUsed.toString()}--${q.transactionId.toString()}'),
// }),
Row(
children: [
ElevatedButton(
onPressed: () {
// print(values);
widget.screenClosed();
Navigator.of(
context,
rootNavigator: true,
).pop(
context,
);
},
child: Text("Continue")),
SizedBox(
width: 10,
),
ElevatedButton(
onPressed: () {
print(widget.scheduleRange);
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.push(
context,
new MaterialPageRoute(
builder: (_) => GluePassthroughUploadPage(
id: widget.schedule_id.toString(),
compoundCode:
widget.compoundCode.toString(),
lotNo: widget.lotNo.toString(),
scheduleRange: widget.scheduleRange,
batchQty: widget.batchQty,
// getAllBatch: getBatch,
)));
});
},
child: Text("Show Add page")),
],
),
],
),
),
// Text("hohohoooooo${batched[0].batchNumber}${batched[0].isUsed}"),
),
);
}
}
Future buildShowDialog(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return Center(
child: CircularProgressIndicator(),
);
});
}
How to remove duplicate list of objects? I'm using Batch as model class. I tried many methods to solve this issue. toSet(), like that.......
For your Batch Model, you can filter with a function like this:
List<Batch> removeDuplicates(List<Batch> items) {
List<Batch> uniqueItems = []; // uniqueList
var uniqueIDs = items
.map((e) => e.uniqueID)
.toSet(); //list if UniqueID to remove duplicates
uniqueIDs.forEach((e) {
uniqueItems.add(items.firstWhere((i) => i.uniqueID == e));
}); // populate uniqueItems with equivalent original Batch items
return uniqueItems;//send back the unique items list
}
Replace uniqueID with the parameter you want to use for filtering duplicates
If you want dealing with more complex objects, store seen ids to the Set and filter away those ones that are already in the set.
final list = ['a', 'a', 'b', 'c', 'c'];
final seen = <String>{};
final uniqueList = list.where((str) => seen.add(str)).toList();
print(uniqueList); // => ['a', 'b', 'c']
With the help of this, You can easily get Unique data from list and it will remove duplicate value
uniqueList = uniqueList.toSet().toList();

List does not appear in the app interface

The idea is that a list appears on my app screen and is updated as I add texts to the textField, but in my tests the list appears empty even though I put test items there.
image error
flutter version 1.0.0
dependences
path_provider: ^1.1.0
code atualization
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'dart:async';
import 'dart:convert';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List _listaTarefas = [];
Future<File> _pegarArquivo() async {
final diretorio = await getApplicationDocumentsDirectory();
return File("${diretorio.path}/dados.json");
}
_salvarArquivo() async {
var arquivo = await _pegarArquivo();
Map<String, dynamic> tarefa = Map();
tarefa['titulo'] = "Teste";
tarefa['realizada'] = false;
_listaTarefas.add(tarefa);
String dados = json.encode(_listaTarefas);
arquivo.writeAsString(dados);
}
_lerArquivo() async {
try {
final arquivo = await _pegarArquivo();
return arquivo.readAsString();
} catch (e) {
return null;
}
}
#override
void initState() {
super.initState();
_lerArquivo().then((dados) {
setState(() {
_listaTarefas = json.decode(dados);
});
});
}
#override
Widget build(BuildContext context) {
_salvarArquivo();
print('Resultado' + _listaTarefas.toString());
return Scaffold(
appBar: AppBar(
title: Text('Lista de tarefas'),
backgroundColor: Colors.purple,
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.purple,
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Adicionar Tarefa'),
content: TextField(
decoration: InputDecoration(
labelText: 'Digite sua tarefa',
),
onChanged: (text) {},
),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text('cancelar'),
),
FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Salvar'),
),
],
);
});
}),
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: _listaTarefas.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_listaTarefas[index]['titulo']),
);
}))
],
),
);
}
}
The problem
When you declare the following method
_lerArquivo() async {
try {
final arquivo = await _pegarArquivo();
return arquivo.readAsStringSync();
} catch (e) {
return Text('erro');
}
}
you're returning a String when you do
return arquivo.readAsStringSync();
and a Text when you do
return Text('erro');
The solution
To fix this, you can either
return a string in the second return:
_lerArquivo() async {
try {
final arquivo = await _pegarArquivo();
return arquivo.readAsStringSync();
} catch (e) {
return 'erro';
}
}
do nothing:
_lerArquivo() async {
final arquivo = await _pegarArquivo();
return arquivo.readAsStringSync();
}
The good practice
To avoid future errors (i.e. transform run-time errors into compile-time errors), declare your variable types, return types and type parameters explicitely:
String _lerArquivo() async {
try {
final arquivo = await _pegarArquivo();
return arquivo.readAsStringSync();
} catch (e) {
// ...
}
}

Displaying Snackbar inside a SearchDelegate

I am using a SearchDelegate and want to display a Snackbar when the user tries to perform a search with an empty query. I've tried returning Scaffold widgets from both the buildSuggestions and buildResults methods and then using a Builder / GlobalKey inside the buildResults method to display a message to the user if the search query has a length of zero. However this leads to the Scaffold's state being updated during the render method which throws an exception. Has anyone dealt with a similar challenge? Seems like a common use case that you would want to display a Snackbar inside your search delegate, yet I can't seem to fathom an easy way to do it.
Figured it out
class DataSearch extends SearchDelegate<String> {
List<Drug> drugList = new List<Drug>();
DataSearch(Future<List<Drug>> listDrugName) {
this.drugListFuture = listDrugName;
}
#override
List<Widget> buildActions(BuildContext context) {
// actions for app bar
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
})
];
}
#override
Widget buildLeading(BuildContext context) {
// leading icon on the left of app bar
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {
// show result from selection
return null;
}
#override
Widget buildSuggestions(BuildContext context) {
return new FutureBuilder(
future: db.getDrugEntries(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData || snapshot.data.length < 1) {
return new Center(
child: new LoadingIndicator(Constants.msgLoading));
} else {
drugList = snapshot.data;
// show when user searches for something
final suggestionList = query.isEmpty
? drugList
: drugList
.where((r) =>
(r.drugId.toLowerCase())
.contains(query.toLowerCase()) ||
(r.fullDrugName.toLowerCase())
.contains(query.toLowerCase()) ||
(r.otherName.toLowerCase())
.contains(query.toLowerCase()) ||
(r.tradeName.toLowerCase())
.contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) {
String drugName = suggestionList[index].genericName;
String drugId = suggestionList[index].drugId;
int queryIndex = drugName.indexOf(query);
if (queryIndex == -1) {
queryIndex = 0;
}
int queryIndexEnd = queryIndex + query.length;
return Container(button//...onTap:_launchExtraContent(context,drugId);
},
itemCount: suggestionList.length,
);
}
});
}
_
_launchExtraContent(BuildContext context, StringtheFileName) async {
try {
//......
} catch (e) {
_showSnackBar(context,'ERROR: Unable to retrieve file please submit a bug report');
}
}
void _showSnackBar(BuildContext context, String text) {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text(
text,
textAlign: TextAlign.center,
),
backgroundColor: Colors.red,
));
}
}