How to implement a network data fetch and then display in checkbox in alert inside showDialog with setState - flutter

I couldn't find a way to fetch data from network API inside showDialog > StatefulBuilder > AlertDialog. After fetching, this data should display in checkboxes and then finally on click ok, the selected checkboxes data is returned to the parent widget. There are more states other than these checkbox states in the alert. But the Navigator.of(context).pop() can return only single value.
Is there a way to rebuild the StatefulBuilder with setState on parent widget. Or some easy hack to rebuild the StatefulBuilder from an outside function like fetchOrderStatus() in the below code. (might be possible with a key on StatefulBuilder, but don't know how).
Below is my code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'dart:convert';
import 'package:recase/recase.dart';
import 'package:woocommerceadmin/src/orders/widgets/OrderDetailsPage.dart';
import 'package:barcode_scan/barcode_scan.dart';
class OrdersListPage extends StatefulWidget {
final String baseurl;
final String username;
final String password;
OrdersListPage({
Key key,
#required this.baseurl,
#required this.username,
#required this.password,
}) : super(key: key);
#override
_OrdersListPageState createState() => _OrdersListPageState();
}
class _OrdersListPageState extends State<OrdersListPage> {
String baseurl;
String username;
String password;
List ordersListData = List();
int page = 1;
bool hasMoreToLoad = true;
bool isListLoading = false;
bool isSearching = false;
String searchValue = "";
String sortOrderByValue = "date";
String sortOrderValue = "desc";
bool isOrderStatusOptionsReady = false;
bool isOrderStatusOptionsError = false;
String orderStatusOptionsError;
Map<String, bool> orderStatusOptions = {};
final scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
new GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
baseurl = widget.baseurl;
username = widget.username;
password = widget.password;
fetchOrdersList();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: _myAppBar(),
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: handleRefresh,
child: Column(
children: <Widget>[
Expanded(
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (hasMoreToLoad &&
!isListLoading &&
scrollInfo.metrics.pixels ==
scrollInfo.metrics.maxScrollExtent) {
handleLoadMore();
}
},
child: ListView.builder(
itemCount: ordersListData.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OrderDetailsPage(
id: ordersListData[index]["id"],
),
),
);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
_orderDate(ordersListData[index]),
_orderIdAndBillingName(
ordersListData[index]),
_orderStatus(ordersListData[index]),
_orderTotal(ordersListData[index])
]),
),
)
]),
),
);
}),
),
),
if (isListLoading)
Container(
height: 60.0,
color: Colors.white,
child: Center(
child: SpinKitFadingCube(
color: Colors.purple,
size: 30.0,
)),
),
],
),
),
);
}
Future<void> fetchOrderStatus() async {
String url =
"$baseurl/wp-json/wc/v3/reports/orders/totals?consumer_key=$username&consumer_secret=$password";
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = false;
});
dynamic response;
try {
response = await http.get(url);
if (response.statusCode == 200) {
if (json.decode(response.body) is List &&
!json.decode(response.body).isEmpty) {
json.decode(response.body).forEach((item) {
if (item is Map) {
orderStatusOptions.putIfAbsent(item["slug"], () => false);
}
});
setState(() {
isOrderStatusOptionsReady = true;
});
} else {
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = true;
orderStatusOptionsError = "Failed to fetch order status options";
});
}
} else {
String errorCode = "";
if (json.decode(response.body) is Map &&
json.decode(response.body).containsKey("code") &&
json.decode(response.body)["code"] is String) {
errorCode = json.decode(response.body)["code"];
}
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = true;
orderStatusOptionsError =
"Failed to fetch order status options. Error: $errorCode";
});
}
} catch (e) {
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = true;
orderStatusOptionsError =
"Failed to fetch order status options. Error: $e";
});
}
}
Widget _myAppBar() {
Widget myAppBar;
myAppBar = AppBar(
title: Text("Orders List"),
actions: <Widget>[
GestureDetector(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Icon(Icons.search),
),
onTap: () {
setState(() {
isSearching = !isSearching;
});
},
),
GestureDetector(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Icon(Icons.filter_list),
),
onTap: _orderFilter,
),
],
);
}
return myAppBar;
}
void _orderFilter() async {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
// fetchOrderStatus();
return StatefulBuilder(builder: (context, StateSetter setState) {
return AlertDialog(
title: Text("Sort & Filter"),
titlePadding: EdgeInsets.fromLTRB(15, 20, 15, 0),
content: Container(
width: 300,
height: 400,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Sort by",
style: Theme.of(context).textTheme.subhead,
),
Row(
children: <Widget>[
Expanded(
child: Container(
child: DropdownButton<String>(
underline: SizedBox.shrink(),
value: sortOrderByValue,
onChanged: (String newValue) {
FocusScope.of(context)
.requestFocus(FocusNode());
setState(() {
sortOrderByValue = newValue;
});
},
items: <String>[
"date",
"id",
"title",
"slug",
"include"
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value.titleCase,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.body1,
),
);
}).toList(),
),
),
),
InkWell(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10),
child: Icon(
Icons.arrow_downward,
color: (sortOrderValue == "desc")
? Theme.of(context).primaryColor
: Colors.black,
),
),
onTap: () {
setState(() {
sortOrderValue = "desc";
});
},
),
InkWell(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10),
child: Icon(
Icons.arrow_upward,
color: (sortOrderValue == "asc")
? Theme.of(context).primaryColor
: Colors.black,
),
),
onTap: () {
setState(() {
sortOrderValue = "asc";
});
},
),
],
),
Text(
"Filter by",
style: Theme.of(context).textTheme.subhead,
),
Text(
"Order Status",
style: Theme.of(context).textTheme.body1.copyWith(
fontWeight: FontWeight.bold, fontSize: 16),
),
isOrderStatusOptionsReady
? ListView(
children:
orderStatusOptions.keys.map((String key) {
return new CheckboxListTile(
title: Text(key),
value: orderStatusOptions[key],
onChanged: (bool value) {
setState(() {
orderStatusOptions[key] = value;
});
},
);
}).toList(),
)
: Container(
child: Center(
child: SpinKitFadingCube(
color: Theme.of(context).primaryColor,
size: 30.0,
),
),
)
],
),
),
),
contentPadding: EdgeInsets.fromLTRB(15, 10, 15, 0),
actions: <Widget>[
FlatButton(
child: Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
});
}
}

You have a couple of options
Fetch the data before showing the dialog. Using either async/await keywords or .then, you wait for the fetching of data to complete, then use the data in the dialog
void _orderFilter() async {
await fetchOrderStatus();
showDialog(...); //Use the response in the dialog
}
Create a new stateful widget for the dialog and have fetchOrderStatus() be a method in that class. This allows you to have more control over what to display as well as state changes in the dialog.

#gaurav-jain I have followed your question from Github where you asked a question about my answer to this problem. How I did it is i have a button that when clicked immediately opens the dialog that then waits for the Future to load data from the API: The async function _showOptions() renders the dialog that renders a list of checkboxes with options fetched from API:
new RaisedButton(
color: Colors.green,
padding: EdgeInsets.all(20.0),
onPressed: () {
if (state._isLoading){
// don't do anything when form is submitting and this button is pressed again
return null;
}
else {
if (state._formKey.currentState.validate()) {
state._showOptions().then((selected){
print(state.selectedOptions);
if (state.selectedOptions.isNotEmpty) {
_submitForm();
}
else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('You have not selected any option'),
actions: <Widget>[
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context, rootNavigator: true).pop();
},
),
],
);
}
);
}
});
}
else {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('Your form has errors. Rectify them and submit again'),
)
);
}
}
},
child: Text(state._isLoading ? 'Submitting...' : 'Submit', style: new TextStyle(color: Colors.white)),
),
The state here is the parent widget's state, but the async dialog has it's own state to make it work. You can refer back to the github comment for the other pieces of the code here https://github.com/flutter/flutter/issues/15194#issuecomment-450490409

As suggested by #wxker, 2nd approach, I have implemented other stateful widget which returns AlertDialog.
Parent Widget Calling showDialog on tap:
IconButton(
icon: Icon(Icons.filter_list),
onPressed: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return OrdersListFiltersModal(
baseurl: widget.baseurl,
username: widget.username,
password: widget.password,
sortOrderByValue: sortOrderByValue,
sortOrderValue: sortOrderValue,
orderStatusOptions: orderStatusOptions,
onSubmit:
(sortOrderByValue, sortOrderValue, orderStatusOptions) {
setState(() {
this.sortOrderByValue = sortOrderByValue;
this.sortOrderValue = sortOrderValue;
this.orderStatusOptions = orderStatusOptions;
});
handleRefresh();
},
);
},
);
},
),
Child stateful widget returning alert with default value and function callback in constructor to change parent widget state.
Widget build(BuildContext context) {
return AlertDialog(
title: Text("Sort & Filter"),
titlePadding: EdgeInsets.fromLTRB(15, 20, 15, 0),
content: Container(
height: 400,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Sort by",
style: Theme.of(context).textTheme.subhead,
),
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Row(
children: <Widget>[
Expanded(
child: Container(
child: DropdownButton<String>(
underline: SizedBox.shrink(),
value: sortOrderByValue,
onChanged: (String newValue) {
FocusScope.of(context).requestFocus(FocusNode());
setState(() {
sortOrderByValue = newValue;
});
},
items: <String>[
"date",
"id",
"title",
"slug",
"include"
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value.titleCase,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.body1,
),
);
}).toList(),
),
),
),
InkWell(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Icon(
Icons.arrow_downward,
color: (sortOrderValue == "desc")
? Theme.of(context).primaryColor
: Colors.black,
),
),
onTap: () {
setState(() {
sortOrderValue = "desc";
});
},
),
InkWell(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Icon(
Icons.arrow_upward,
color: (sortOrderValue == "asc")
? Theme.of(context).primaryColor
: Colors.black,
),
),
onTap: () {
setState(() {
sortOrderValue = "asc";
});
},
),
],
),
),
Text(
"Filter by",
style: Theme.of(context).textTheme.subhead,
),
SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
"Order Status",
style: Theme.of(context)
.textTheme
.body1
.copyWith(fontWeight: FontWeight.bold, fontSize: 16),
),
),
SizedBox(
height: 10,
),
isOrderStatusOptionsError
? Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Text(
orderStatusOptionsError,
style: Theme.of(context).textTheme.body1,
),
),
),
],
)
: isOrderStatusOptionsReady
? Column(
children: orderStatusOptions.keys.map((String key) {
return GestureDetector(
onTap: () {
setState(() {
orderStatusOptions[key] =
!orderStatusOptions[key];
});
},
child: Container(
color: Colors.transparent,
height: 30,
child: Row(
children: <Widget>[
Checkbox(
value: orderStatusOptions[key],
onChanged: (bool value) {
setState(() {
orderStatusOptions[key] = value;
});
},
),
Expanded(
child: Text(
key.titleCase,
style:
Theme.of(context).textTheme.body1,
),
),
],
),
),
);
}).toList(),
)
: Container(
padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
child: Center(
child: SpinKitPulse(
color: Theme.of(context).primaryColor,
size: 50,
),
),
)
],
),
),
),
contentPadding: EdgeInsets.fromLTRB(15, 10, 15, 0),
actions: <Widget>[
FlatButton(
child: Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text("Ok"),
onPressed: () {
widget.onSubmit(
sortOrderByValue, sortOrderValue, orderStatusOptions);
Navigator.of(context).pop();
},
)
],
);
}
Future<void> fetchOrderStatusOptions() async {
String url =
"${widget.baseurl}?consumer_key=${widget.username}&consumer_secret=${widget.password}";
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = false;
});
http.Response response;
try {
response = await http.get(url);
if (response.statusCode == 200) {
if (json.decode(response.body) is List &&
!json.decode(response.body).isEmpty) {
Map<String, bool> tempMap = orderStatusOptions;
json.decode(response.body).forEach((item) {
if (item is Map &&
item.containsKey("slug") &&
item["slug"] is String &&
item["slug"].isNotEmpty) {
tempMap.putIfAbsent(item["slug"], () => false);
}
});
setState(() {
isOrderStatusOptionsReady = true;
orderStatusOptions = tempMap;
});
} else {
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = true;
orderStatusOptionsError = "Failed to fetch order status options";
});
}
} else {
String errorCode = "";
if (json.decode(response.body) is Map &&
json.decode(response.body).containsKey("code") &&
json.decode(response.body)["code"] is String) {
errorCode = json.decode(response.body)["code"];
}
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = true;
orderStatusOptionsError =
"Failed to fetch order status options. Error: $errorCode";
});
}
} catch (e) {
setState(() {
isOrderStatusOptionsReady = false;
isOrderStatusOptionsError = true;
orderStatusOptionsError =
"Failed to fetch order status options. Error: $e";
});
}
}
}

Related

Error : Failed to detect image file format using the file header. File header was [0x3c 0x68 0x74 0x6d 0x6c 0x3e 0x0a 0x20 0x20 0x20]

I'm trying to display an image from Firestore in to my UI. But it returns the error above, and the file format also changes when I run it on Edge (not on physical device or Emulator). I can't figure out how. Here's my code.
class ViewPola extends StatefulWidget {
const ViewPola({Key? key}) : super(key: key);
static String id = 'view_pola';
#override
State<ViewPola> createState() => _ViewPolaState();
}
class _ViewPolaState extends State<ViewPola> {
Function getSnaps = () async {
final polaMap = {
'Kode Pola': '',
'Bagian Pola': '',
'image_url': '',
};
FirebaseFirestore.instance
.collection('PolaWillyJKT')
.limit(1)
.get()
.then((snapshot) {
if (snapshot.size == 0) {
FirebaseFirestore.instance.collection('PolaWillyJKT').add(polaMap);
FirebaseFirestore.instance.collection('PolaWillyJKT');
print('add');
} else {
print('disini nge get');
var a = FirebaseFirestore.instance.collection('PolaWillyJKT').get();
Map<String, dynamic> data = a as Map<String, dynamic>;
print(data);
}
});
};
var _selectedItem;
var _showList = false;
#override
void initState() {
getSnaps();
super.initState();
}
final Stream<QuerySnapshot> _polaWilly =
FirebaseFirestore.instance.collection('PolaWillyJKT').snapshots();
#override
Widget build(BuildContext context) {
final screenHeight = ScreenInfo.screenHeight(context);
final screenWidth = ScreenInfo.screenWidth(context);
return StreamBuilder<QuerySnapshot>(
stream: _polaWilly,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return SafeArea(
child: Scaffold(
body: Padding(
padding: EdgeInsets.all(25),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
'Pilih Bagian Pola',
style: TextStyle(fontSize: 25),
),
const SizedBox(
height: 20,
),
DropdownButton(
isExpanded: true,
value: _selectedItem,
items: snapshot.data?.docs
.map(
(value) => DropdownMenuItem(
value: value.get("Bagian Pola"),
child: Text('${value.get("Bagian Pola")}'),
),
)
.toList(),
onChanged: (newValue) {
setState(() {
_selectedItem = newValue.toString();
_showList = true;
});
}),
Padding(
padding: const EdgeInsets.all(25),
child: Visibility(
visible: _showList,
child: Container(
height: screenHeight * 0.4,
child: ListView(
children: snapshot.data!.docs
.where(
(e) => e.get("Bagian Pola") == _selectedItem)
.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return Center(
child: Column(
children: [
Text(
'Bagian Pola: ${data["Bagian Pola"]}',
style: TextStyle(fontSize: 15),
),
const SizedBox(
height: 15,
),
Text(
'Kode Pola : ${data["Kode Pola"]}',
style: TextStyle(fontSize: 15),
),
const SizedBox(
height: 15,
),
Image(
image:
NetworkImage(document.get("Foto Pola")),
height: 200,
width: 200,
), // this is the Image widget where I tried to put the image from firestore
Text(document.get('Foto Pola').toString()),
],
),
);
}).toList(),
),
),
),
),
],
),
),
),
);
},
);
}
}
and here's the class that uploads the image to Firestore
class Input_Pola extends StatefulWidget {
const Input_Pola({Key? key}) : super(key: key);
static String id = 'input_pola';
#override
State<Input_Pola> createState() => _Input_PolaState();
}
class _Input_PolaState extends State<Input_Pola> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
void _checkDuplicate() {
if (options.contains(_textfieldValue.text)) {
// Display bottom sheet that says item already exists
_scaffoldKey.currentState?.showBottomSheet((context) => Container(
height: 300,
child: Column(
children: [
const Text('Item already exists'),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Dismiss'))
],
),
));
} else {
// Add item to options list
setState(() {
options.add(_textfieldValue.text);
});
}
}
XFile? image;
final ImagePicker picker = ImagePicker();
String _image_url = '';
void _addToFirebase(String dropdownValue, String _kodePolaController) {
var imageFile = File(image!.path);
String fileName = pth.basename(imageFile.path);
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child("WillyJKT/polaWillyJKT");
UploadTask uploadTask = ref.putFile(imageFile);
uploadTask.whenComplete(() async {
var url = await ref.getDownloadURL();
_image_url = url.toString();
});
FirebaseFirestore.instance
.collection('PolaWillyJKT')
.doc(_selectedOption)
.set({
'Bagian Pola': _selectedOption,
'Kode Pola': _kodePolaController,
'Foto Pola': _image_url
});
}
String _dropdownValue = 'kg';
String _property1 = '';
String _property2 = '';
String _property3 = '';
bool _isOptionSelected = false;
final TextEditingController _kodePolaController = TextEditingController();
var _selectedOption;
final TextEditingController _textfieldValue = TextEditingController();
final List<String> options = [];
#override
void initState() {
super.initState();
_selectedOption = options.isNotEmpty ? options[0] : null;
}
//we can upload image from camera or from gallery based on parameter
Future getImage(ImageSource media) async {
var img = await picker.pickImage(source: media);
setState(() {
image = img;
});
}
void myAlert() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
title: Text('Please choose media to select'),
content: Container(
height: MediaQuery.of(context).size.height / 6,
child: Column(
children: [
ElevatedButton(
//if user click this button, user can upload image from gallery
onPressed: () {
Navigator.pop(context);
getImage(ImageSource.gallery);
},
child: Row(
children: [
Icon(Icons.image),
Text('From Gallery'),
],
),
),
ElevatedButton(
//if user click this button. user can upload image from camera
onPressed: () {
Navigator.pop(context);
getImage(ImageSource.camera);
},
child: Row(
children: [
Icon(Icons.camera),
Text('From Camera'),
],
),
),
],
),
),
);
});
}
#override
Widget build(BuildContext context) {
final screenHeight = ScreenInfo.screenHeight(context);
final screenWidth = ScreenInfo.screenWidth(context);
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
_addToFirebase(_dropdownValue, _kodePolaController.text);
},
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(25),
child: Container(
height: screenHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextFormField(
decoration: const InputDecoration(
hintText: 'Input Pola',
border: UnderlineInputBorder(),
),
onChanged: (value) {
setState(() {
_textfieldValue.text = value;
});
},
),
DropdownButton<String>(
value: _selectedOption,
onChanged: (value) {
setState(() {
_selectedOption = value!;
_isOptionSelected = true;
_kodePolaController.clear();
});
},
hint: const Text('Input from Text Field Above'),
items: options.map((option) {
return DropdownMenuItem<String>(
value: option,
child: Text(option),
);
}).toList(),
),
TextButton(
onPressed: _checkDuplicate,
child: const Text("Add Option"),
),
Visibility(
visible: _isOptionSelected,
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextField(
controller: _kodePolaController,
decoration: const InputDecoration(
labelText: "Kode Pola"),
onChanged: (value) {
setState(() {
_property1 = value;
});
},
),
const SizedBox(height: 20,),
ElevatedButton(
onPressed: () {
myAlert();
},
child: Text('Upload Photo'),
),
SizedBox(
height: 10,
),
//if image not null show the image
//if image null show text
image != null
? Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.file(
//to show image, you type like this.
File(image!.path),
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
height: 300,
),
),
)
: const Text(
"No Image",
style: TextStyle(fontSize: 20),
),
],
),
),
)
],
),
),
),
),
),
);
}
}
It also displays the error on Edge, but when I build the apk and run it on my physical device, it just shows nothing on the screen except for the data that's got above it. Any idea on how I can fix this?
var a = FirebaseFirestore.instance.collection('PolaWillyJKT').get();
This returns a promise but not the actual data. In fact it could still be fetching the data when you attempt to convert it to a map.
You can await
var a = await FirebaseFirestore.instance.collection('PolaWillyJKT').get();
myDoc = a.docs.first();
Or use a callback that will run once the collection fetch completes:
FirebaseFirestore.instance.collection('PolaWillyJKT').get().then((response) => {
print(response);
});

why my FormBuilder does not reset the values?

I use a FormBuilder with a global key, I have a showModalBottomSheet in which i have my filters rendered, before I click the apply button my filters are reset, but after I applied the filters and I want to reset my filters, my _formKey.currentState?.reset() stops working.
I think the problem is in _buildFilterField but I don't quite understand how to reset it.
final _formKey = GlobalKey<FormBuilderState>();
var filterData;
bool isFilterLoading = true;
Future showFilter(context) => showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) => StatefulBuilder(builder: (context, innerSetState) {
Future.delayed(const Duration(milliseconds: 700), () {
innerSetState(() {
isFilterLoading = false;
});
});
return SafeArea(
child: FormBuilder(
key: _formKey,
child: Container(
child: isFilterLoading != true
? Column(children: [
Padding(
padding: const EdgeInsets.only(),
child: Row(
children: [
TextButton(
onPressed: () {
_formKey.currentState?.reset();
},
child: const Text(
'Сброс',
style: TextStyle(
color: Colors.black, fontSize: 16),
)),
],
),
),
_myRangeSlider(),
_buildFilterField(filterData),
Padding(
padding:
const EdgeInsets.only(top: 10, bottom: 10),
child: SizedBox(
child: ElevatedButton(
onPressed: () {
_formKey.currentState!.save();
filterValues = _formKey.currentState!.value;
setState(() {
String encodedString =
filterValues.keys.map((key) {
return key +
'=' +
Uri.encodeQueryComponent(
filterValues[key].toString());
}).join('&');
filters = encodedString;
page = 1;
list.clear();
productFuture = getProducts(val, filters);
});
Navigator.pop(context);
},
child: const Text(
'Показать результаты',
),
),
),
),
])
: const Center(child: CircularProgressIndicator())),
),
);
}));
Widget _buildFilterField(Map<String, dynamic> field) {
List<Widget> children = [];
print(filterValues);
field.keys.forEach((key) {
if (field[key]["type"] == 'radio') {
children.add(FormBuilderRadioGroup(
initialValue: filterValues?[key] ?? field[key]["initial_value"],
name: field[key]["value"],
decoration: const InputDecoration(
border: InputBorder.none,
),
options: [
for (var option in field[key]["data"])
FormBuilderFieldOption(
value: option['value'],
child: Text(
option['text'],
)),
],
));
}
});
return children.isEmpty
? Container()
: Column(
children: children,
);
}

How to implement objectbox into flutter appilcation

I am working on an app, and need help trying to change my save method to object box. I have been using path_provider to save data but want to switch it to the object box database but I am struggling to do it. The goal is to have each timer button be clicked to record a time and present them back to the user to see how long each task/button took. Below is my code for my ViewModel and my timer_page dart files.
#Entity()
class StudyViewModel {
static List<Study> studies = [];
static List<ValueChanged<ElapsedTime>> timerListeners =
<ValueChanged<ElapsedTime>>[];
static Stopwatch stopwatch = new Stopwatch();
/// load from file...
static Future load() async {
try {
File file = await getFile();
String studiesJson = await file.readAsString();
if (studiesJson.isNotEmpty) {
List studiesParsed = json.decode(studiesJson);
studies = studiesParsed.map((i) => Study.fromJson(i)).toList();
}
} catch (e) {
print(e);
}
}
static Future<File> getFile() async {
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
return File('$path/studies.json');
}
static Future saveFile() async {
File file = await getFile();
file.writeAsString(json.encode(studies));
}
SizedBox(
height: 600,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: widget.tasks.map((element) {
final isActive = activeTask != null && activeTask == element;
return GestureDetector(
onTap: () {
// set active task or toggle is active
if (isActive) {
setState(() {
activeTask = null;
StudyViewModel.stopwatch.start();
disable = true;
});
} else {
setState(() {
activeTask = element;
StudyViewModel.stopwatch.stop();
disable = false;
});
}
},
child: Container(
color: isActive ? Colors.amber : Colors.green,
padding: EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
element.name,
style: TextStyle(color: Colors.white, fontSize: 25),
textAlign: TextAlign.center,
),
Text(
element.elapsedTime
)
]
),
),
);
}).toList(),
),
),
Expanded(
child: timerText,
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: disable
? null
: () {
setState(() {
StudyViewModel.stopwatch.reset();
});
},
color: Colors.red,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Reset",
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
RaisedButton(
onPressed: disable
? null
: () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Do you wish to save a time study?'),
actions: <Widget>[
FlatButton(
child: Text('Accept'),
onPressed: () async {
StudyViewModel.saveFile();
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
]
);
}
);

Local camera in first video call is not working in Flutter app with Agora (using agora_rtc_engine 4.0.7)

I integrated Agora in Flutter Application with the help of agora_rtc_engine 4.0.7, but upon making a video call for the very first time the local camera view is not working. When we disconnect the call and call back again then everything works fine, the local camera view started working.
Again when we kill the application from Phone memory and rerun it then also the same problem occurs for the first time.
VideoCallingScreen.dart file
class VideoCallingScreen extends StatefulWidget {
String doctorId;
String bookingId;
VideoCallingScreen(this.doctorId, this.bookingId);
#override
_VideoCallingScreenState createState() => _VideoCallingScreenState();
}
class _VideoCallingScreenState extends State<VideoCallingScreen> {
int? _remoteUid;
RtcEngine? _engine;
bool isJoined = false,
switchCamera = true,
switchRender = true,
muteAudio = false,
muteVideo = false;
bool remoteUserMicMute = false, remoteUserVideoMute = false;
bool resizeVideo = false;
ServerHandler _serverHandler = ServerHandler();
String? token;
String? channelName;
String? channelId;
late user.Details userDetails;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState() {
super.initState();
getAgoraToken().then((value) {
if (value) {
initForAgora();
} else {
_showMyDialog();
}
});
// initForAgora();
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('No Channel Found'),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text('No video channel has been created by the Doctor'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Ok'),
onPressed: () async {
// int count = 0;
Navigator.pop(context);
Navigator.pop(_scaffoldKey.currentContext!);
},
),
],
);
},
);
}
Future<bool> getAgoraToken() async {
await Screen.keepOn(true);
var tokenBody = await _serverHandler.joinAgoraChannel(
widget.doctorId, widget.bookingId);
print('token Body from videoPage' + tokenBody.toString());
if (tokenBody['success'] == 1) {
setState(() {
token = tokenBody['channel']['access_token_patient'];
channelName = tokenBody['channel']['channel_name'];
print('**********Token Set********' + token!);
channelId = tokenBody['channel']['id'].toString();
});
return true;
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"Unable to get Video Call Token, Please check your internet Connection and try again."),
));
return false;
}
}
Future<void> initForAgora() async {
// retrieve permissions
await [Permission.microphone, Permission.camera].request();
userDetails = await _serverHandler.getUserProfile();
//create the engine
_engine = await RtcEngine.create(appId);
await _engine?.enableVideo();
_engine?.setEventHandler(
RtcEngineEventHandler(
joinChannelSuccess: (String channel, int uid, int elapsed) async {
print("local user $uid joined");
// await _engine!.enableVideo();
},
userJoined: (int uid, int elapsed) {
print("remote user $uid joined");
setState(() {
_remoteUid = uid;
});
},
tokenPrivilegeWillExpire: (token) async {
await getAgoraToken();
await _engine?.renewToken(token);
},
userOffline: (int uid, UserOfflineReason reason) {
print("remote user $uid left channel");
// _engine!.enableVideo();
setState(() {
_remoteUid = null;
});
_userLeftTheCall();
},
userMuteVideo: (int uid, bool isMute) {
print('Audio Mutted');
setState(() {
remoteUserVideoMute = isMute;
});
},
userMuteAudio: (int uid, bool isMute) {
print('Audio Mutted');
setState(() {
remoteUserMicMute = isMute;
});
},
),
);
await getAgoraToken();
await _engine?.joinChannel(token, channelName!, null, userDetails.id!);
}
// Create UI with local view and remote view
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: Stack(
children: [
Center(
child:
resizeVideo ? _renderLocalPreview() : _renderRemoteVideo(),
),
if (remoteUserVideoMute)
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: Padding(
padding: const EdgeInsets.only(bottom: 32),
child: Center(
child: Text(
'Doctor video Paused',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
),
if (remoteUserMicMute)
Padding(
padding: const EdgeInsets.only(top: 32),
child: Center(
child: Text(
'Doctor Mic Muted',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
Positioned(
top: 8,
left: 8,
child: InkWell(
//Uncomment it to unable resize
// onTap: () {
// setState(() {
// resizeVideo = !resizeVideo;
// });
// },
child: Container(
width: 100,
height: 120,
child: Stack(
children: [
ImageFiltered(
imageFilter: muteVideo
? ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0)
: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: resizeVideo
? _renderRemoteVideo()
: _renderLocalPreview(), // Widget that is blurred
),
if (muteVideo)
Positioned(
top: 4,
left: 4,
child: Icon(
Icons.videocam_off_outlined,
color: Colors.white,
size: 32,
),
),
if (muteAudio)
Positioned(
bottom: 4,
right: 4,
child: Icon(
Icons.mic_off_outlined,
color: Colors.white,
size: 32,
),
),
],
),
),
),
),
Positioned(
bottom: 32,
right: 8,
left: 8,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
InkWell(
onTap: () async {
await Screen.keepOn(false);
await _engine?.leaveChannel();
await _serverHandler.leaveChannel(channelId!);
Navigator.pop(_scaffoldKey.currentContext!);
},
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.red),
child: Icon(
Icons.call_end,
color: Colors.white,
),
),
),
InkWell(
onTap: this._switchCamera,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
Icons.flip_camera_android_rounded,
color: Colors.black87,
),
),
),
InkWell(
onTap: this._onToggleMuteVideo,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
muteVideo
? Icons.videocam_off_outlined
: Icons.videocam_outlined,
color: Colors.black87,
),
),
),
InkWell(
onTap: this._onToggleMute,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
muteAudio
? Icons.mic_off_outlined
: Icons.mic_none_outlined,
color: Colors.black87,
),
),
),
],
),
)
],
),
),
),
);
}
// current user video
Widget _renderLocalPreview() {
return RtcLocalView.SurfaceView();
}
// remote user video
Widget _renderRemoteVideo() {
// return RtcRemoteView.SurfaceView(uid: 70);
if (_remoteUid != null) {
return RtcRemoteView.SurfaceView(uid: _remoteUid!);
} else {
return Text(
'Please wait, doctor is joining shortly',
style: TextStyle(
color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
);
}
}
_switchCamera() {
_engine?.switchCamera().then((value) {
setState(() {
switchCamera = !switchCamera;
});
}).catchError((err) {
log('switchCamera $err');
});
}
void _onToggleMute() {
setState(() {
muteAudio = !muteAudio;
});
_engine!.muteLocalAudioStream(muteAudio);
}
void _onToggleMuteVideo() {
setState(() {
muteVideo = !muteVideo;
});
_engine!.muteLocalVideoStream(muteVideo);
}
Future<bool> _onWillPop() async {
return (await showDialog(
context: _scaffoldKey.currentContext!,
builder: (context) => new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Do you want to exit exit Video Call?'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(_scaffoldKey.currentContext!),
child: new Text('No'),
),
TextButton(
onPressed: () async {
await Screen.keepOn(false);
await _serverHandler.leaveChannel(channelId!);
await _engine?.leaveChannel();
Navigator.pop(_scaffoldKey.currentContext!);
Navigator.pop(_scaffoldKey.currentContext!);
},
child: new Text('Yes'),
),
],
),
)) ??
false;
}
_userLeftTheCall() async {
return (await showDialog(
context: _scaffoldKey.currentContext!,
builder: (context) => new AlertDialog(
title: new Text('Doctor Left'),
content: new Text('Doctor left this call please join Again'),
actions: <Widget>[
TextButton(
onPressed: () async {
// await _serverHandler.leaveChannel(channelId!);
await Screen.keepOn(false);
await _engine?.leaveChannel();
Navigator.pop(_scaffoldKey.currentContext!);
Navigator.pop(_scaffoldKey.currentContext!);
// Navigator.of(context).pop(true);
},
child: new Text('Okay'),
),
],
),
)) ?? false;
}
}
Please ignore things which are not relevent. Also the log is too long to share, the log keeps on running during the entire video call.
Mobile Screenshot
Thank You

I dont want to display all the records of table in listview but I want to display records of only particular customer in flutter

I have a screen which shows list of customers using listview. Next when I click on a customer I want to show the notes(records) only of that particular customer(customerId) in next screen in listview. I know how to display all the records of table. but how to display only certain records?? Neither there is any error nor the listview is being displayed. I dont know where am I going wrong.
List<CustomerNote> cnoteList;
int count = 0;
if (cnoteList == null) {
cnoteList = List<CustomerNote>();
updateCustomerNotes();
}
db_service.dart
Future<List<CustomerNote>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("noteDetails WHERE custId = '$customer'");
int count = res.length;
List<CustomerNote> cnotelist = List<CustomerNote>();
for (int i = 0; i < count; i++) {
cnotelist.add(CustomerNote.fromMap(res[i]));
}
return cnotelist;
}
People_List.dart //this is the file which displays list of customers
import 'package:customer/models/Note.dart';
import 'package:customer/models/addCustomer.dart';
import 'package:customer/screens/New_Note.dart';
import 'package:customer/screens/Note_info.dart';
import 'package:customer/screens/User_Settings.dart';
import 'package:customer/screens/add_person.dart';
import 'package:customer/services/db_service.dart';
import 'package:customer/utils/database_helper.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:sqflite/sqflite.dart';
class People_List extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return People_ListState();
}
}
class People_ListState extends State<People_List> with SingleTickerProviderStateMixin{
DBService dbService = DBService();
List<AddCustomer> customerList;
int count = 0;
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
var _isSelectedItemIndex;
TextEditingController _searchQuery;
bool _isSearching = false;
String searchQuery = "Search query";
#override
void initState() {
super.initState();
_searchQuery = new TextEditingController();
}
void _startSearch() {
print("open search box");
ModalRoute
.of(context)
.addLocalHistoryEntry(new LocalHistoryEntry(onRemove: _stopSearching));
setState(() {
_isSearching = true;
});
}
void _stopSearching() {
_clearSearchQuery();
setState(() {
_isSearching = false;
});
}
void _clearSearchQuery() {
print("close search box");
setState(() {
_searchQuery.clear();
updateSearchQuery("Search query");
});
}
Widget _buildTitle(BuildContext context) {
var horizontalTitleAlignment =
Platform.isIOS ? CrossAxisAlignment.center : CrossAxisAlignment.start;
return new InkWell(
onTap: () => scaffoldKey.currentState.openDrawer(),
child: new Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: horizontalTitleAlignment,
children: <Widget>[
const Text(''),
],
),
),
);
}
Widget _buildSearchField() {
return new TextField(
controller: _searchQuery,
autofocus: true,
decoration: const InputDecoration(
hintText: 'Search...',
border: InputBorder.none,
hintStyle: const TextStyle(color: Colors.white30),
),
style: const TextStyle(color: Colors.white, fontSize: 16.0),
onChanged: updateSearchQuery,
);
}
void updateSearchQuery(String newQuery) {
setState(() {
searchQuery = newQuery;
});
print("search query " + newQuery);
}
List<Widget> _buildActions() {
if (_isSearching) {
return <Widget>[
new IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
if (_searchQuery == null || _searchQuery.text.isEmpty) {
Navigator.pop(context);
return;
}
_clearSearchQuery();
},
),
];
}
return <Widget>[
new IconButton(
icon: const Icon(Icons.search),
onPressed: _startSearch,
),
];
}
#override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
if (customerList == null) {
customerList = List<AddCustomer>();
updateListView();
}
return Scaffold(
appBar: new AppBar(
leading: _isSearching ? const BackButton() : null,
title: _isSearching ? _buildSearchField() : _buildTitle(context),
actions: _buildActions(),
),
body:getCustomerListView(),
floatingActionButton: FloatingActionButton(
onPressed: () {
navigateToCustomer(AddCustomer(), 'Add Person');
},
child: const Icon(Icons.add),
),
bottomNavigationBar:Row (
children: <Widget>[
buildNavBarItem(Icons.home,0,"Home"),
buildNavBarItem(Icons.fiber_new_rounded,1,"Upcoming"),
buildNavBarItem(Icons.history,2,"History"),
buildNavBarItem(Icons.account_circle,3,"Account"),
],
),
);
}
ListView getCustomerListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
/*trailing: CircleAvatar(
backgroundColor: getPriorityColor(this.noteList[position].priority),
child: getPriorityIcon(this.noteList[position].priority),
),*/
title: Text(this.customerList[position].custName, style: titleStyle,),
//subtitle: Text(this.customerList[position].date),
onTap: () {
},
),
);
},
);
}
void navigateToCustomer(AddCustomer customer, String title) async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return AddPerson(customer, title);
}));
if (result == true) {
updateListView();
}
}
void updateListView() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
Future<List<AddCustomer>> customerListFuture = dbService.getCustomerList();
customerListFuture.then((customerList) {
setState(() {
this.customerList = customerList;
this.count = customerList.length;
});
});
});
}
Widget buildNavBarItem(IconData icon,int index,title) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
return GestureDetector(
onTap: () {
setState(() {
_isSelectedItemIndex=index;
if(_isSelectedItemIndex==3) {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => User_Settings()));
}
});
},
child: Container(
height: height * 0.09,
width: width / 4,
decoration: index==_isSelectedItemIndex?BoxDecoration(
border: Border(
bottom: BorderSide(width: 4,color: Theme.of(context).primaryColor),
),
gradient: LinearGradient(colors: [
Theme.of(context).primaryColor.withOpacity(0.3),
Theme.of(context).primaryColor.withOpacity(0.015),
],begin: Alignment.bottomCenter,end: Alignment.topCenter)
):BoxDecoration(),
child: Column(
children: <Widget>[
InkWell(
child: Icon(icon,
color: index==_isSelectedItemIndex? Theme.of(context).primaryColor:Colors.black54,
),
),
Text(title)
],)),
);
}
}
Note_Info.dart
class Note_Info extends StatefulWidget{
final String appBarTitle;
final AddCustomer customer;
Note_Info(this. customer, this.appBarTitle);
#override
State<StatefulWidget> createState() {
return Note_InfoState(this.customer,this.appBarTitle);
}
}
class Note_InfoState extends State<Note_Info> {
CustomerNote note=CustomerNote();
DBService dbService = DBService();
List<CustomerNote> cnoteList;
int count = 0;
String appBarTitle;
AddCustomer customer;
Note_InfoState(this.customer, this.appBarTitle);
PickedFile _imageFile;
final ImagePicker _picker = ImagePicker();
bool rememberMe = false;
DateTime _date = DateTime.now();
TextEditingController custNameController = TextEditingController();
void getImage(ImageSource source) async {
final pickedFile = await _picker.getImage(
source: source);
setState(() {
_imageFile = pickedFile;
});
}
#override
Widget build(BuildContext context) {
if (noteList == null) {
noteList = List<CustomerNote>();
updateCustomerNotes();
}
var height = MediaQuery.of(context).size.height;
custNameController.text = customer.custName;
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.add,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => NewNote()));
},
)
],
),
body: Container(
child: Column(
children: <Widget>[
TextField(controller: custNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(children: [
ImageProfile(),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: IconButton(
icon: Icon(
Icons.call,
color: Colors.green,
size: 45,
),
onPressed: () {
},
),
),
],),
),
SizedBox(
height: 50,
child: AppBar(
bottom: TabBar(
tabs: [
Tab(
text: "All",
),
Tab(
text: "Pending",
),
Tab(
text: "Cancelled",
),
Tab(
text: "Completed",
),
],
),
),
),
// create widgets for each tab bar here
Expanded(
child: TabBarView(
children: [
// first tab bar view widget
Container(
child: getNoteListView(),
),
// second tab bar view widget
Container(
child: Center(
child: Text(
'Pending Items',
),
),
),
Container(
child: Center(
child: Text(
'Cancelled',
),
),
),
Container(
child: Center(
child: Text(
'Completed',
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme
.of(context)
.primaryColorDark,
textColor: Colors.white,
child: Text('Save', textScaleFactor: 1.5,),
onPressed: () {
setState(() {
//_reset();
});
},
),
),
),
]
),
)
));
}
void updateCustomerNotes() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
int customerId=customer.custId;
Future<List<CustomerNote>> noteListFuture = dbService.getCustomerNotes(customerId);
noteListFuture.then((cnoteList) {
setState(() {
this.cnoteList = cnoteList;
//this.count = cnoteList.length;
});
});
});
}
ListView getNoteListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
title: Text(this.cnoteList[position].note, style: titleStyle,),
subtitle: Text(this.cnoteList[position].date),
trailing: GestureDetector(
child: Icon(Icons.delete, color: Colors.grey,),
onTap: () {
},
),
onTap: () {
},
),
);
},
);
}
void _showSnackBar(BuildContext context, String message) {
final snackBar = SnackBar(content: Text(message));
Scaffold.of(context).showSnackBar(snackBar);
}
Widget ImageProfile() {
return Center(
child: CircleAvatar(
radius: 80.0,
backgroundImage: AssetImage('images/person_icon.jpg')
),
);
}
}
If u want to get some specific data from the server then you need to provide (where: ) in your query such as
List<Map> result = await db.query(
DatabaseHelper.table,
columns: columnsToSelect,
where: whereString,
whereArgs: whereArguments);
// print the results
result.forEach((row) => print(row));
// {_id: 1, name: Bob, age: 23}
}
Note your query can be different from the above one.
and if you want to get the same specific data from already fetched data then also you need to use the where clause such as
final outData = responseData.where((i) => i.userId == customerId).toList();
and then pass the outData to next page through params.