Update page data after pop Navigation Updated #5 - flutter

I have page Navigate to second page with variable (dID) with await to return same value if it has been changed ,at the second page if i did't do anything the value must return without any changes ,if i changed slider the value of (dID) must be increase by (1) ,but when i Navigate.pop the return value is same without increasing.
New update : After many test i did the problem is in the second page ,when i change the slider value i call a function to get the new value (newSavedDayId) ,and it is get it correctly but just inside the function ,after the slider change and get the new value ,it is returned to null :
newSavedDayId = Instance of 'Future<dynamic>'
second page which return value :
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '../classes/viewdigree.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Days extends StatefulWidget {
#override
_DaysState createState() => _DaysState();
}
TextEditingController insertedDegree = TextEditingController();
class _DaysState extends State<Days> {
#override
Widget build(BuildContext context) {
List digrees = [];
var widthView = MediaQuery.of(context).size.width;
Map rdata = ModalRoute.of(context).settings.arguments;
var did = int.parse(rdata['dayId'].toString());
var u_id = rdata['userID'];
var m_id = rdata['courseId'];
var lang = rdata['lang'];
int w_id;
var newSavedDayId = rdata['savedDayID']; ----// received value
var username;
if (did <= 6) {
w_id = 1;
} else if (did <= 12) {
w_id = 2;
} else if (did <= 18) {
w_id = 3;
} else {
w_id = 4;
}
Future<List> fetchDigrees() async {
var url =
'https://srdtraining.com/api/controller/activities/activiy_list.php?d_id=$did&m_id=$m_id&u_id=$u_id';
var response = await http.get(url);
var data = jsonDecode(response.body);
print(data);
for (var x in data) {
Digree newdigree = Digree(
x['index'],
x['title_k'],
x['title_a'],
x['aya'],
x['link'],
x['activity_k'],
x['activity_a'],
x['act_id'],
x['mydigree']);
digrees.add(newdigree);
}
return digrees;
}
// Insert Func
send_degree(uId, actId, degree, w_id, did, m_id) async {
var sendData = {
'u_id': uId.toString(),
'act_id': actId.toString(),
'digree': degree.toString(),
'm_id': m_id.toString(),
'd_id': did.toString(),
'w_id': w_id.toString()
};
var url = 'https://srdtraining.com/api/controller/data/changedata.php';
var response = await http.post(url, body: sendData);
}
// End of Insert Func
//get user status .................. // this is the function to get new value
void getUserStatus() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
username = preferences.getString('username');
});
var url =
"http://srdtraining.com/api/controller/users/status_user.php?username=$username";
var response = await http.get(url);
var data = jsonDecode(response.body);
setState(() {
newSavedDayId = int.parse(data['d_id']); ----// Set New value by getting it from API after increasing by server.
});
print('newSavedDayId = $newSavedDayId');----// here it is print new value with increasing correctly
}
// End get user
return FutureBuilder(
future: fetchDigrees(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('./assets/images/background.png'),
fit: BoxFit.cover)),
child: Center(
child: Text("Loading"),
),
),
);
} else {
YoutubePlayerController _controller = YoutubePlayerController(
initialVideoId: snapshot.data[0].link,
flags: YoutubePlayerFlags(
autoPlay: false,
mute: false,
));
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context, newSavedDayId);
}),
backgroundColor: Colors.pink[900],
title: Text(
'ژیان و قورئان',
style: TextStyle(fontSize: 32),
),
centerTitle: true,
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('./assets/images/background.png'),
fit: BoxFit.cover)),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: ListView(
padding: EdgeInsets.fromLTRB(25, 20, 25, 20),
shrinkWrap: true,
children: <Widget>[
Text(
lang == 'k'
? snapshot.data[0].title_k
: snapshot.data[0].title_a,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 32, color: Colors.white)),
//for top margin
SizedBox(height: 20.0),
// dexription
Container(
padding: const EdgeInsets.all(15),
width: widthView,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: const Color.fromRGBO(180, 80, 80, 0.3)),
child: Text(snapshot.data[0].aya,
textAlign: TextAlign.justify,
textDirection: TextDirection.rtl,
style: TextStyle(
fontFamily: 'Hafs',
fontSize: 26,
color: Colors.greenAccent[100])),
),
// now populating your ListView for `Directionality`
Column(
children: <Widget>[
// Start activities
Column(
children: snapshot.data.map<Widget>((item) {
double _value =
double.parse(item.mydigree.toString());
return Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
width: 2, color: Colors.white),
color:
Color.fromRGBO(230, 200, 200, 0.2)),
width: widthView,
padding: EdgeInsets.all(25),
margin: EdgeInsets.fromLTRB(0, 25, 0, 25),
child: Column(
children: <Widget>[
Text(
lang == 'k'
? item.activity_k
: item.activity_a,
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 28, color: Colors.white),
),
SizedBox(
height: 15,
),
Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.yellow[200]
.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 20,
)
],
borderRadius:
BorderRadius.circular(15),
color:
Color.fromRGBO(0, 0, 0, 0.4)),
width: widthView,
padding: EdgeInsets.all(10),
child: Slider(
max: 100,
min: 0,
divisions: 100,
value: _value,
label: _value.round().toString(),
onChanged: (val) {
send_degree(u_id, item.act_id,
val, w_id, did, m_id);
},
onChangeEnd: (val) {
setState(() {
_value = val;
});
getUserStatus(); /// when i print the value here it is give me null
}),
),
SizedBox(
height: 10,
),
Text('$_value',
style: TextStyle(
fontSize: 26,
color: Colors.white))
],
),
)
],
),
);
}).toList()),
// End activities
SizedBox(
height: 20,
),
Text('خەلەکا ئەڤرو',
textAlign: TextAlign.right,
style:
TextStyle(fontSize: 26, color: Colors.yellow)),
SizedBox(
height: 20,
),
YoutubePlayer(
controller: _controller,
showVideoProgressIndicator: true,
progressIndicatorColor: Colors.blueAccent,
),
],
),
],
),
),
);
}
});
}
}

you can usef ValueChanged onChanged and do a callback to the page you want to update ,
you can passe the onChanged funtion on the parametre ,
when you change your value use : onChanged()
than in the page you want to see the update on call your function with set state ,

I solved it by merging two function in one :
Future<List> fetchDigrees() async {
var url =
'https://srdtraining.com/api/controller/activities/activiy_list.php?d_id=$did&m_id=$m_id&u_id=$u_id';
var response = await http.get(url);
var data = jsonDecode(response.body);
print(data);
for (var x in data) {
Digree newdigree = Digree(
x['index'],
x['title_k'],
x['title_a'],
x['aya'],
x['link'],
x['activity_k'],
x['activity_a'],
x['act_id'],
x['mydigree']);
digrees.add(newdigree);
}
return digrees;
}
void getUserStatus() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
username = preferences.getString('username');
});
var url =
"http://srdtraining.com/api/controller/users/status_user.php?username=$username";
var response = await http.get(url);
var data = jsonDecode(response.body);
setState(() {
newSavedDayId = int.parse(data['d_id']); ----// Set New value by getting it from API after increasing by server.
});
and they now like this and worked correctly :
Future<List> fetchDigrees() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
username = preferences.getString('username');
var url1 =
"http://srdtraining.com/api/controller/users/status_user.php?username=$username";
var response1 = await http.get(url1);
var data1 = jsonDecode(response1.body);
newSavedDayId = int.parse(data1['d_id']);
print('newSavedDayId before retrun = $newSavedDayId');
var url =
'https://srdtraining.com/api/controller/activities/activiy_list.php?d_id=$did&m_id=$m_id&u_id=$u_id';
var response = await http.get(url);
var data = jsonDecode(response.body);
print(data);
for (var x in data) {
Digree newdigree = Digree(
x['index'],
x['title_k'],
x['title_a'],
x['aya'],
x['link'],
x['activity_k'],
x['activity_a'],
x['act_id'],
x['mydigree']);
digrees.add(newdigree);
}
return digrees;
}

Related

I am having trouble iterating through an array of objects

I am trying to go through an array of objects, I stored them in my SharedPreferences where I go the data from firebase and add the quantity for each object, now I only want to display the title, price, and quantity of the product in the cart. I was able to pull all the values belonging to the product to the cart screen but how to loop through the nested values in the cart screen is the problem. please can anyone help me still learning more on flutter?
Cart screen
#override
Widget build(BuildContext context) {
SharedPreferences prefs = SharedPreferences.getInstance() as SharedPreferences;
var cart = prefs.getStringList('userCart');
return Row(
children: [
SizedBox(
width: getProportionateScreenWidth(88),
child: AspectRatio(
aspectRatio: 0.88,
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color(0XFFF5F6F9),
borderRadius: BorderRadius.circular(15),
),
child: Image.network(cart![0]),
// child: Image.network(cart.product.images[0]),
),
),
),
SizedBox(
width: getProportionateScreenWidth(20),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
cart.first,
// cart.product.title,
style: TextStyle(fontSize: 16, color: Colors.black),
maxLines: 2,
),
const SizedBox(
height: 10,
),
Text.rich(
TextSpan(
text: "\$${cart.product.price}",
style: TextStyle(
color: kPrimaryColor,
),
children: [
TextSpan(
text: " x${cart.numOfItem}",
style: TextStyle(
color: kTextColor,
),
),
],
),
),
],
)
],
);
}
Storing the data from firebase and adding quantity
Future<void> checkItemInCart(
Product product, int quantity, BuildContext context) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// convert to map
var product_str = product.toMap();
// combine product with quantity
String productWithQuantity =
product_str.toString() + '-quantity-' + quantity.toString();
// check if project exists first
List<String> userCartPref = (prefs.getStringList('userCart') ?? <String>[]);
['Product-quantity-2'];
/*
update {
check if found
}
*/
List<String> temp = (prefs.getStringList('userCart') ?? <String>[]);
// add f
//userCartPref ['iphone 1','laptop 3'];
// temp ['laptop 3'];
var foundInCart = false;
for (var i = 0; i < userCartPref.length; i++) {
var item = userCartPref[i];
var items = item.split('-quantity-'); //list [product,quantity]
var old_product = items[0];
var old_qty = items[1];
if (old_product.contains(product.pid)) {
foundInCart = true;
// product exists
// delete the current item
temp.removeAt(i);
// set pref to temp
prefs.setStringList('userCart', temp);
// sum the quantity 2 1
String finalQuantity = (quantity + int.parse(old_qty)).toString();
// create string for pref with the updated quantity
String updatedProductWithQuantity =
product_str.toString() + '-quantity-' + finalQuantity;
//add item with the updated quantity iphone 2
addItemToCart(updatedProductWithQuantity, context);
showSnackBar(context, "Quantity has been updated successfully");
break;
}
}
if (userCartPref.length == 0 || foundInCart == false) {
addItemToCart(productWithQuantity, context);
showSnackBar(context, "Product added successfully to cart");
}
await getProducts();
}
Future<void> addItemToCart(String product, BuildContext context) async {
// await clearPref();
print("inside");
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> tempCartList = (prefs.getStringList('userCart') ?? <String>[]);
// print(tempCartList);
tempCartList.add(product);
prefs.setStringList('userCart', tempCartList);
}
Future<void> getProducts() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
List<String> tempCartList =
(preferences.getStringList('userCart') ?? <String>[]);
for (var i = 0; i < tempCartList.length; i++) {
var item = tempCartList[i];
var items = item.split('-quantity-');
var product_ = items[0];
var quantity_ = items[1];
}
}
you can use ListView.builder or GridView.builder to iterate over the array and render them on screen. So if I use ListView.builder, my code in cart screen would look like:
return ListView.builder(
itemCount: cart.length, //length of cart
itemBuilder: (context, index) {
return Row(
children: [
SizedBox(
width: getProportionateScreenWidth(88),
child: AspectRatio(
aspectRatio: 0.88,
child: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color(0XFFF5F6F9),
borderRadius: BorderRadius.circular(15),
),
child: Image.network(cart![index]),
// child: Image.network(cart.product.images[0]),
),
),
),
SizedBox(
width: getProportionateScreenWidth(20),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
cart[index].product.title,
// cart.product.title,
style: TextStyle(fontSize: 16, color: Colors.black),
maxLines: 2,
),
const SizedBox(
height: 10,
),
Text.rich(
TextSpan(
text: "\$${cart[index].product.price}",
style: TextStyle(
color: kPrimaryColor,
),
children: [
TextSpan(
text: " x${cart[index].numOfItem}",
style: TextStyle(
color: kTextColor,
),
),
],
),
),
],
)
],
);
},
);

Map<dynamic,dynamic> is null after loading currencies from API

Any idea why my currencies map is null in the CurrencyConverterState class? I am loading currencies from an API to my currencies map in class API (see code for class API) and also trying to set state after the loading is done. After loading the currencies from the API to my currencies map I can also access the rates from the map so that means that my map is working fine and is not null. I did that test by printing a currency rate and it was fine. But that works just in the API class. The problem is that as soon as I test my currencies map in class CurrencyConverterState it says that the map is null and I am stuck in circular progress indicator (see code for class CurrencyConverterState). I dont really know why it says that the map is null. Any help appreciated.
API class code:
class API
{
var fromTextController = new TextEditingController();
Map<dynamic, dynamic> currencies;
String fromCurrency;
String toCurrency;
String result;
API(String from, String to){
fromCurrency = from;
toCurrency = to;
}
Future<dynamic> loadCurrencies() async {
String uri = "http://api.openrates.io/latest";
var response = await http
.get(Uri.encodeFull(uri), headers: {"Accept": "application/json"});
var responseBody = json.decode(response.body);
Map curMap = responseBody['rates'];
currencies = curMap;
setState(() {});
print (currencies["SEK"]);
}
Future<dynamic> doConversion() async {
String uri =
"http://api.openrates.io/latest?base=$fromCurrency&symbols=$toCurrency";
var response = await http
.get(Uri.encodeFull(uri), headers: {"Accept": "application/json"});
var responseBody = json.decode(response.body);
setState(() {
result = (double.parse(fromTextController.text) *
(responseBody["rates"][toCurrency]))
.toString();
});
setState(() {});
return "Success";
}
void setState(Null Function() param0) {}
}
CurrencyConverterState class code:
class CurrencyConverterState extends State<CurrencyConverter> {
final API api = new API("USD", "SEK");
CurrencyConverterState();
int i = 1;
#override
void initState() {
super.initState();
api.loadCurrencies();
api.fromTextController.addListener(doConversion);
setState(() {
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Theme.of(context).primaryColor,
body: api.currencies?.keys == null
? Center(child: CircularProgressIndicator())
: Stack(children: [
Positioned(
top: 30,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 2,
width: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 10,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Converter',
style: TextStyle(
color: Colors.black, fontSize: 22.0),
),
ListTile(
title: TextField(
controller: api.fromTextController,
decoration: InputDecoration(
hintText: 'Enter a number'),
style: TextStyle(
fontSize: 20.0, color: Colors.black),
keyboardType: TextInputType.numberWithOptions(
decimal: true),
),
trailing:
buildDropDownButton(api.fromCurrency),
),
ListTile(
title: Chip(
label: api.result != null
? Container(
width: 1000,
height: 40,
child: Text(
api.result,
style: Theme.of(context)
.textTheme
.headline4,
),
)
: Container(
width: 1000,
height: 40,
child: Text(" "))),
trailing:
buildDropDownButton(api.toCurrency),
),
],
)),
),
),
),
]));
}
Widget buildDropDownButton(String currencyCategory) {
return DropdownButton(
value: currencyCategory,
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
items: api.currencies.keys.map((dynamic value) => DropdownMenuItem(
value: value,
child: Row(children: <Widget>[
Text(value),
])))
.toList(),
onChanged: (dynamic value) {
if (currencyCategory == api.fromCurrency) {
api.fromCurrency = value;
} else {
api.toCurrency = value;
}
setState(() {});
});
}
doConversion() {
api.doConversion();
setState(() {});
}
}
Actually, you are retrieving currencies before they get retrieved and you are never updating the UIs when they are retrieved.
This is a possible solution:
//In API class
Future<Map<String,dynamic>> loadCurrencies() async {
String uri = "http://api.openrates.io/latest";
var response = await http
.get(Uri.encodeFull(uri), headers: {"Accept": "application/json"});
var responseBody = json.decode(response.body);
Map<String,dynamic> curMap = responseBody['rates'];
print (currencies["SEK"]);
return curMap;
}
Then in your main class use a futureBuilder:
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Theme.of(context).primaryColor,
body: FutureBuilder(
future: api.loadCurrencies(),
builder: (context, currencies) =>{
return currencies==null?
? Center(child: CircularProgressIndicator())
: Stack(/*rest of your code*/);
})
);

changing slider value as List item value in flutter New version

Yesterday i have ask question about this topic ,yesterday it was test project to understand the issue ,today i tried to apply what i learned on my app ,but i get small error i can't fix it.
I have this class file (viewdegree.dart):
class Digree {
final int index;
final String title_k;
final String title_a;
final String aya;
final String link;
final String activity_k;
final String activity_a;
String act_id;
String mydigree;
Digree(this.index, this.title_k, this.title_a, this.aya, this.link,
this.activity_k, this.activity_a, this.act_id, this.mydigree);
}
I have this page which import above class ,the page send request to API to display some rows ,in each row i have slider to detect the degree for each item data.
when i change the slider value it send post request to server to add degree to the row or update it ,the i want to setstate the value of Slider to new degree.
the page code :
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:jiyanUquraan/classes/viewdigree.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
class DisplayList extends StatefulWidget {
#override
_DisplayListState createState() => _DisplayListState();
}
TextEditingController insertedDegree = TextEditingController();
var video_link = '';
class _DisplayListState extends State<DisplayList> {
#override
Widget build(BuildContext context) {
List digrees = [];
var widthView = MediaQuery.of(context).size.width;
Map rdata = ModalRoute.of(context).settings.arguments;
var did = int.parse(rdata['dayId'].toString());
var u_id = rdata['userID'];
var m_id = rdata['courseId'];
int w_id;
if (did <= 6) {
w_id = 1;
} else if (did <= 12) {
w_id = 2;
} else if (did <= 18) {
w_id = 3;
} else {
w_id = 4;
}
Future<List> fetchDigrees() async {
var url =
'http://10.0.2.2/jiyan/test/api/activities/activiy_list.php?d_id=$did&m_id=$m_id&u_id=$u_id';
var response = await http.get(url);
var data = jsonDecode(response.body);
print(data);
for (var x in data) {
Digree newdigree = Digree(
x['index'],
x['title_k'],
x['title_a'],
x['aya'],
x['link'],
x['activity_k'],
x['activity_a'],
x['act_id'],
x['mydigree']);
digrees.add(newdigree);
}
return digrees;
}
// Insert Func
send_degree(uId, actId, degree, w_id, did, m_id) async {
var sendData = {
'u_id': uId.toString(),
'act_id': actId.toString(),
'degree': degree.toString(),
'm_id': m_id.toString(),
'd_id': did.toString(),
'w_id': w_id.toString()
};
var url = 'http://10.0.2.2/jiyan/test/api/data/changedata.php';
var response = await http.post(url, body: sendData);
var data = jsonDecode(response.body);
if (data.status) {
print('OK');
}
}
// End of Insert Func
return FutureBuilder(
future: fetchDigrees(),
builder: (context, snapshot) {
Map rdata = ModalRoute.of(context).settings.arguments;
var lang = rdata['lang'];
if (snapshot.data == null) {
return Center(
child: Text("Loading"),
);
} else {
YoutubePlayerController _controller = YoutubePlayerController(
initialVideoId: snapshot.data[0].link,
flags: YoutubePlayerFlags(
autoPlay: false,
mute: false,
));
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: ListView(
padding: EdgeInsets.fromLTRB(25, 20, 25, 20),
shrinkWrap: true,
children: <Widget>[
Text(
lang == 'k'
? snapshot.data[0].title_k
: snapshot.data[0].title_a,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 32, color: Colors.white)),
//for top margin
SizedBox(height: 20.0),
// dexription
Container(
padding: const EdgeInsets.all(15),
width: widthView,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: const Color.fromRGBO(180, 80, 80, 0.3)),
child: Text(snapshot.data[0].aya,
textAlign: TextAlign.justify,
textDirection: TextDirection.rtl,
style: TextStyle(
fontSize: 26, color: Colors.greenAccent[100])),
),
// now populating your ListView for `Directionality`
Column(
children: <Widget>[
// Start activities
Column(
children: snapshot.data.map<Widget>((item) {
double _value;
var xx = double.parse(item.mydigree);
if (xx > 0) {
_value = double.parse(item.mydigree);
} else {
_value = 0.0;
}
return Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
width: 2, color: Colors.white),
color: Color.fromRGBO(230, 200, 200, 0.2)),
width: widthView,
padding: EdgeInsets.all(25),
margin: EdgeInsets.fromLTRB(0, 25, 0, 25),
child: Column(
children: <Widget>[
Text(
lang == 'k'
? item.activity_k
: item.activity_a,
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 28, color: Colors.white),
),
SizedBox(
height: 15,
),
Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.yellow[200]
.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 20,
)
],
borderRadius:
BorderRadius.circular(15),
color:
Color.fromRGBO(0, 0, 0, 0.4)),
width: widthView,
padding: EdgeInsets.all(10),
child: Slider(
max: 100,
min: 0,
divisions: 20,
value: _value,
label: _value.round().toString(),
onChanged: (val) {
send_degree(u_id, item.act_id, val,
w_id, did, m_id);
setState(() {
_value = val;
item.mydigree = val.toString();
});
},
))
],
),
)
],
),
);
}).toList()),
// End activities
SizedBox(
height: 20,
),
Text('خەلەکا ئەڤرو',
textAlign: TextAlign.right,
style: TextStyle(fontSize: 26, color: Colors.yellow)),
SizedBox(
height: 20,
),
YoutubePlayer(
controller: _controller,
showVideoProgressIndicator: true,
progressIndicatorColor: Colors.blueAccent,
),
],
),
],
),
);
}
});
}
}
When i change the slider value it is come back to zero and degree with zero value inserted on server as show on video.
https://streamable.com/0ejpel
How can i fixed it.
Best Regards
because your variable is set value in build method, every time you call setState, your variable is set again and slider show default value again.
for solve this problem, you should set your variable out of the build method.
EDIT:
change your code like this:
List digrees = [];
var widthView;
Map rdata;
var did;
var u_id;
var m_id;
var w_id;
#override
void initState() {
super.initState();
widthView = MediaQuery.of(context).size.width;
rdata = ModalRoute.of(context).settings.arguments;
did = int.parse(rdata['dayId'].toString());
u_id = rdata['userID'];
m_id = rdata['courseId'];
w_id;
if (did <= 6) {
w_id = 1;
} else if (did <= 12) {
w_id = 2;
} else if (did <= 18) {
w_id = 3;
} else {
w_id = 4;
}
}
Future<List> fetchDigrees() async {
...
}
Future<void> send_degree(uId, actId, degree, w_id, did, m_id) async {
...
}
Widget build(BuildContext context) {
// put your future builder here
}
and in slider onChange method:
send_degree(u_id, item.act_id, val,
w_id, did, m_id).then((_){
setState(() {
_value = val;
});
});
this is not the ideal solution and best code. but you can change it to be better.

FLUTTER: How can I show the weather Icon from Open Weather Map?

I Would like to show open weather icons on my app but I'm not sure how I can do so. A sample of the data I'm getting from openweather map is below, and I've also included an example of how I'm getting the other data.
My Code:
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'GetLocation.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
void main() {
runApp(AuraWeather());
}
class AuraWeather extends StatefulWidget {
#override
_AuraWeatherState createState() => _AuraWeatherState();
}
class _AuraWeatherState extends State<AuraWeather> {
var apiKey = '5f10958d807d5c7e333ec2e54c4a5b16';
var weatherIcon;
var description;
var maxTemp;
var minTemp;
var format_sunRise;
var sunRise;
var format_sunSet;
var format_sunRiseEnd;
var format_sunSetEnd;
var sunSet;
var temp;
var city;
#override
Widget build(BuildContext context) {
setState(() {
getLocation();
});
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(displayBackground()),
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaY: 2, sigmaX: 2),
child: Container(
color: Colors.black.withOpacity(0.5),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
Container(
child: Center(
child: Text(
'$city',
style: TextStyle(
fontSize: 25,
color: Colors.white,
fontFamily: 'Roboto',
),
),
),
),
Container(
child: Icon(
FontAwesomeIcons.locationArrow,
color: Colors.white,
),
),
Container(
margin: EdgeInsets.only(top: 80),
child: Text(
'$temp' + '°',
style: TextStyle(
fontSize: 50,
color: Colors.white,
fontWeight: FontWeight.w600),
),
),
],
),
Container(
margin: EdgeInsets.only(top: 30),
child: Icon(
Icons.wb_sunny,
color: Colors.white,
size: 120,
),
),
Container(
child: Center(
child: Text(
'$maxTemp ° | $minTemp °',
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
),
Container(
child: Text(
'$description',
style: TextStyle(fontSize: 20,
color: Colors.white,
fontFamily: 'Roboto mono',),
),
),
Container(
child: FlatButton(
child: Icon(
Icons.refresh,
color: Colors.white,
size: 40,
),
color: Colors.transparent,
onPressed: () {
setState(
() {
getLocation();
},
);
},
),
),
],
),
),
),
),
),
);
}
// display background images based on current time
displayBackground() {
var now = DateTime.now();
//var currentTime = DateFormat.jm().format(now);
print('Sunrise time $format_sunRise');
print('Sunset time $format_sunSet');
print('Current time $now');
if ((now.isAfter(format_sunRise)) && (now.isBefore(format_sunRiseEnd))){
print('Morning');
return'images/Moon.png';
}else if((now.isAfter(format_sunRiseEnd)) && (now.isBefore(format_sunSet))){
return 'images/Sun.png';
}else if ((now.isAfter(format_sunSet)) && (now.isBefore(format_sunSetEnd))){
print('Evening');
return 'images/Moon.png';
}else if((now.isAfter(format_sunSetEnd)) && (now.isBefore(format_sunRise))){
return 'images/Blood.png';
}
}
//getLocation
void getLocation() async {
Getlocation getlocation = Getlocation();
await getlocation.getCurrentLocation();
print(getlocation.latitude);
print(getlocation.longitude);
print(getlocation.city);
city = getlocation.city;
getTemp(getlocation.latitude, getlocation.longitude);
}
//Get current temp
Future<void> getTemp(double lat, double lon) async {
var now = DateTime.now();
DateFormat dateFormat = new DateFormat.Hm();
http.Response response = await http.get(
'https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=$apiKey&units=metric');
//print(response.body);
var dataDecoded = jsonDecode(response.body);
description = dataDecoded['weather'][0]['description'];
temp = dataDecoded['main']['temp'];
temp = temp.toInt();
maxTemp = dataDecoded['main']['temp_max'];
maxTemp = maxTemp.toInt();
minTemp = dataDecoded['main']['temp_min'];
minTemp = minTemp.toInt();
sunRise = dataDecoded['sys']['sunrise'];
format_sunRise = DateTime.fromMillisecondsSinceEpoch(sunRise*1000);
format_sunRiseEnd = format_sunRise.add(Duration(hours: 1));
sunSet = dataDecoded['sys']['sunset'];
format_sunSet = DateTime.fromMillisecondsSinceEpoch(sunSet*1000);
format_sunSetEnd = format_sunSet.add(Duration(hours: 1));
print('Current temp $temp');
print('Max temp $maxTemp');
print('Min temp $minTemp');
}
}
SAMPLE DATA:
{
coord: {
lon: 139.01,
lat: 35.02
},
weather: [
{
id: 800,
main: "Clear",
description: "clear sky",
icon: "01n"
}
],
base: "stations",
main: {
temp: 285.514,
pressure: 1013.75,
humidity: 100,
temp_min: 285.514,
temp_max: 285.514,
sea_level: 1023.22,
grnd_level: 1013.75
},
wind: {
speed: 5.52,
deg: 311
},
clouds: {
all: 0
},
dt: 1485792967,
sys: {
message: 0.0025,
country: "JP",
sunrise: 1485726240,
sunset: 1485763863
},
id: 1907296,
name: "Tawarano",
cod: 200
}
From the data above, I'm able to get: temp, temp_max, temp_min and description. This is how I've done it.
CODE:
http.Response response = await http.get(
'https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=$apiKey&units=metric');
//print(response.body);
var dataDecoded = jsonDecode(response.body);
description = dataDecoded['weather'][0]['description'];
temp = dataDecoded['main']['temp'];
temp = temp.toInt();
maxTemp = dataDecoded['main']['temp_max'];
maxTemp = maxTemp.toInt();
minTemp = dataDecoded['main']['temp_min'];
minTemp = minTemp.toInt();
How can I get to show the ICON from url? Icon will be shown inside container number 5 in Scaffold widgget.
For this api icon code have an url actually, and it will be like that in your case.
icon_url = "http://openweathermap.org/img/w/" + dataDecoded["weather"]["icon"] +".png"
and you can use it as image:
Image.network(icon_url),
or directly:
Image.network('http://openweathermap.org/img/w/${dataDecoded["weather"]["icon"]}.png',),

How display a list of data order by date?

Here is the result now :
It is much better but i Don't know why BELSHINA BOBRUISK is not centered vertically. As you can see the others team are centered vertically. FC SMOELVITCHI is centered. Strange. Too i would like display the "2020-06-01" in mobile format so if it is french mobile it will be "01-06-2020".
And another question i Don't know why my mobile app use the theme with fontfamily but not all. I have some pages with a part of data in good family font and the other part in default font, its is really strange
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'package:flutter_app/menu_member.dart';
import 'package:flutter_app/globals.dart' as globals;
import 'package:flutter_app/appbar_draw.dart';
// Create a Form widget.
class Affiche_Matchs extends StatefulWidget {
#override
_Affiche_Matchs_State createState() {
return _Affiche_Matchs_State();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class _Affiche_Matchs_State extends State<Affiche_Matchs> {
#override
final _formKey = GlobalKey<FormState>();
List<String> radioValues = [];
Future<List<Match>> grid;
Future <List<Match>> Liste_Match_Display() async {
// SERVER LOGIN API URL
var url = 'https://www.easytrafic.fr/game_app/display_matchs.php';
// Starting Web API Call.
var response = await http.get(url,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});
// Getting Server response into variable.
var jsondata = json.decode(response.body);
List<Match> Matchs = [];
var i=0;
for (var u in jsondata) {
i=i+1;
Match match = Match(u["id"],u["equipe1"],u["equipe2"],u["type_prono"],u["date_debut"],u["heure_debut"]);
Matchs.add(match);
radioValues.add("");
}
return Matchs;
}
void initState() {
grid = Liste_Match_Display();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: drawappbar(true),
drawer: new DrawerOnly(className: Affiche_Matchs()),
body:
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child:
FutureBuilder(
future: grid,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return new Center(child: new CircularProgressIndicator(),);
default:
if(snapshot.hasError) {
return new Center(child: new Text('Error: ${snapshot.error}'),);
}
else {
List<Match> values = snapshot.data;
Match lastitem;
lastitem=values[0];
if (values.isEmpty) {
return Container(
child: Center(
child: Text("Aucun match disponible !!!")
)
);
}
else {
return Form(
key: _formKey,
child: ListView.builder(itemCount: values.length,itemBuilder: (_,index) {
bool header = lastitem.date_debut !=
values[index].date_debut;
lastitem = values[index];
return Column(
children: [
(header || index == 0)
?
Container(
height: 30,
margin: EdgeInsets.only(top:10),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue[700],
width: 2,
),
color: Colors.blue[700]
),
child : new Text(values[index].date_debut,textAlign: TextAlign.center,style: TextStyle(fontSize: 18.0,fontWeight: FontWeight.w500,color: Colors.white),),
)// here display header
:
Container(),
Container(
margin: EdgeInsets.only(top:20,bottom:20),
child: Center(
child: Text(values[index].heure_debut),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(values[index].equipe1,style: TextStyle(fontSize:12)),
draw_grid("1", index, values[index].typeprono),
draw_grid("N", index, values[index].typeprono), //
draw_grid("2", index, values[index].typeprono), //
Text(values[index].equipe2,style: TextStyle(fontSize:12)),
]
),
]
);
}
)
);
}
};
};
}
),
),
);
}
draw_grid (String choix, int index,String type_prono) {
if (type_prono.contains(choix)) {
return new InkWell(
onTap: () {
setState(() {
if (radioValues[index] == choix) {
radioValues[index] = "";
}
else {
radioValues[index] = choix;
}
});
print(radioValues);
},
child:
Container(
height: 30.0,
width: 30.0,
margin: EdgeInsets.only(right: 2,left: 2),
child: new Center(
child: new Text(choix,
style: new TextStyle(
color:
radioValues[index] == choix ? Colors.white : Colors.red,
//fontWeight: FontWeight.bold,
fontSize: 18.0, fontWeight: FontWeight.w900)),
),
decoration: new BoxDecoration(
color: radioValues[index] == choix
? Colors.red
: Colors.white,
border: new Border.all(
width: 2.0,
color: radioValues[index] == choix
? Colors.red
: Colors.red),
borderRadius: const BorderRadius.all(const Radius.circular(5)),
),
),
);
}
else {
return Text("");
}
}
}
class Match {
final String id;
final String equipe1;
final String equipe2;
final String typeprono;
final String date_debut;
final String heure_debut;
const Match(this.id,this.equipe1, this.equipe2, this.typeprono,this.date_debut,this.heure_debut);
}
You have to sort you list base on date and then you can display by checking you have to display header or not.
Following code help you to understand more and then you can implement.
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
class DeleteWidget extends StatefulWidget {
#override
_DeleteWidgetState createState() => _DeleteWidgetState();
}
class _DeleteWidgetState extends State<DeleteWidget> {
final _formKey = GlobalKey<FormState>();
List<String> radioValues = [];
Future<List<Match>> grid;
Future<List<Match>> Liste_Match_Display() async {
// SERVER LOGIN API URL
var url = 'https://www.easytrafic.fr/game_app/display_matchs.php';
// Starting Web API Call.
var response = await http.get(url, headers: {
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOjE1ODg5NTQ0NDgsImlhdCI6MTU4ODk1NDQ0OCwiZXhwIjoxNTg5MDE0NDQ4LCJkYXRhIjp7ImlkIjoiMSIsImVtYWlsIjoicGFzMzBAbmV0Y291cnJpZXIuY29tIn19.-jcyoxtkNVWWagune6EOjInjBgObyxf9gweXJrA2MxLL5fRTW1pkFSFrJOW8uYzhVpaZ4CF9A-c_m8akUq74NA '
});
// Getting Server response into variable.
var jsondata = json.decode(response.body);
List<Match> Matchs = [];
var i = 0;
for (var u in jsondata) {
i = i + 1;
Match match = Match(u["id"], u["equipe1"], u["equipe2"], u["type_prono"],
u["date_debut"], u["heure_debut"]);
Matchs.add(match);
radioValues.add("");
}
return Matchs;
}
void initState() {
grid = Liste_Match_Display();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
// appBar: drawappbar(true),
//drawer: new DrawerOnly(className: Affiche_Matchs()),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
future: grid,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return new Center(
child: new CircularProgressIndicator(),
);
default:
if (snapshot.hasError) {
return new Center(
child: new Text('Error: ${snapshot.error}'),
);
} else {
List<Match> values = snapshot.data;
Match lastitem;
lastitem = values[0];
if (values.isEmpty) {
return Container(
child: Center(
child: Text("Aucun match disponible !!!")));
} else {
return Form(
key: _formKey,
child: ListView.builder(
itemCount: values.length,
itemBuilder: (_, index) {
bool header = lastitem.date_debut !=
values[index].date_debut;
lastitem = values[index];
return Column(
children: [
(header || index == 0)
? Container(
height: 30,
margin: EdgeInsets.only(top: 10),
width: MediaQuery.of(context)
.size
.width,
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue[700],
width: 2,
),
color: Colors.blue[700]),
child: new Text(
values[index].date_debut,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Colors.white),
),
) // here display header
: Container(),
Text(values[index].heure_debut),
Text(values[index].equipe1),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
draw_grid("1", index,
values[index].typeprono),
draw_grid("N", index,
values[index].typeprono), //
draw_grid("2", index,
values[index].typeprono), //
],
),
Text(values[index].equipe2),
// here display whole item
],
);
}));
}
}
;
}
;
}),
),
);
}
draw_grid(String choix, int index, String type_prono) {
if (type_prono.contains(choix)) {
return new InkWell(
onTap: () {
setState(() {
if (radioValues[index] == choix) {
radioValues[index] = "";
} else {
radioValues[index] = choix;
}
});
print(radioValues);
},
child: Container(
height: 40.0,
width: 40.0,
child: new Center(
child: new Text(choix,
style: new TextStyle(
color:
radioValues[index] == choix ? Colors.white : Colors.red,
//fontWeight: FontWeight.bold,
fontSize: 18.0,
fontWeight: FontWeight.w900)),
),
decoration: new BoxDecoration(
color: radioValues[index] == choix ? Colors.red : Colors.white,
border: new Border.all(
width: 2.0,
color: radioValues[index] == choix ? Colors.red : Colors.red),
borderRadius: const BorderRadius.all(const Radius.circular(5)),
),
),
);
} else {
return Text("");
}
}
}
class Match {
final String id;
final String equipe1;
final String equipe2;
final String typeprono;
final String date_debut;
final String heure_debut;
const Match(this.id, this.equipe1, this.equipe2, this.typeprono,
this.date_debut, this.heure_debut);
}