children: [
Text('${cPrayerName} at ${cPrayerTime}'),
Text('Remining time : $remingTime!)'
]
I put my cPrayerName and cPrayerTime and remingTime in a flip widget. at the start of the app, those variables empty the I execute a function that fetch data from API and add that reposne to a list List<PrayerTimeClass> prayerTime = []; then I check my condition then assign it to those variables String cPrayerName = ""; , var cPrayerTime = ""; but it takes some time to see on flip widget i want to get rid of i need imiditate results
Future fetchPrayerTimeNExDay() async {
var time = DateTime.now();
setState(() {
nextDayDate = "$year-$month-$day";
});
Response response =
await dio.get("http://52.90.175.175/api/prayer-time/get/$currentDate");
if (response.data["data"] != null) {
prayerTimeNexDay.add(PrayerTimeClass.fromJson(response.data["data"]));
}
This is condition i check
Dio dio = Dio();
static List<PrayerTimeClass> prayerTime = [];
Future fetchPrayerTime() async {
String year = DateTime.now().year.toString();
String month = DateTime.now().month.toString().padLeft(2, '0');
String day = DateTime.now().day.toString().padLeft(2, '0');
var time = DateTime.now();
setState(() {
currentDate = "$year-$month-$day";
});
Response response =
await dio.get("http://localhost/api/prayer-time/get/$currentDate");
if (response.data["data"] != null) {
prayerTime.add(PrayerTimeClass.fromJson(response.data["data"]));
DateTime fajirTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(
"${DateTime.now().toString().substring(0, 10)} ${prayerTime[0].fajir}");
DateTime dhuhrTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(
"${DateTime.now().toString().substring(0, 10)} ${prayerTime[0].dhuhar}");
DateTime asrTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(
"${DateTime.now().toString().substring(0, 10)} ${prayerTime[0].asr}");
DateTime magribTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(
"${DateTime.now().toString().substring(0, 10)} ${prayerTime[0].magrib}");
DateTime ishaTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(
"${DateTime.now().toString().substring(0, 10)} ${prayerTime[0].isha}");
DateTime now = DateTime.now();
DateTime nextDayFajirTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(
"${DateTime.now().toString().substring(0, 10)} ${prayerTimeNexDay[0].fajir}");
if (now.isBefore(fajirTime)) {
setState(() {
cPrayerName = "Fajr";
cPrayerTime = DateFormat.Hms().format(fajirTime);
remingTime = fajirTime.difference(now);
});
} else if (now.isAfter(fajirTime) && now.isBefore(dhuhrTime)) {
setState(() {
cPrayerName = "Duhur";
cPrayerTime = DateFormat.Hms().format(dhuhrTime);
remingTime = dhuhrTime.difference(now);
});
} else if (now.isAfter(dhuhrTime) && now.isBefore(asrTime)) {
setState(() {
cPrayerName = "Asr";
cPrayerTime = DateFormat.Hms().format(asrTime);
remingTime = asrTime.difference(now);
});
} else if (now.isAfter(asrTime) && now.isBefore(magribTime)) {
setState(() {
cPrayerName = "Magrib";
cPrayerTime = DateFormat.Hms().format(magribTime);
remingTime = magribTime.difference(now);
});
} else if (now.isAfter(magribTime) && now.isBefore(ishaTime)) {
setState(() {
cPrayerName = "Isha";
cPrayerTime = DateFormat.Hms().format(ishaTime);
remingTime = ishaTime.difference(now);
});
} else {
setState(() {
cPrayerName = "Prayer";
cPrayerTime = "Fajr";
remingTime = fajirTime.difference(now);
});
}
}
}
Call your API in your init method and instead of using FutureBuilder, use only the Builder if needed or even you don't need it at all if you're saving data into a list.
Note: You shouldn't call async method directly into the init method. Instead put it into another method/function that is not async or returning anything.
Here's an example how it'll be done:
getPrayerTime(){
Future fetchPrayerTimeNExDay() async {
//api logic
}
}
getPrayerTimeNextDay(){
Future fetchPrayerTime() async {
//api logic
}
}
#override
void initState() {
super.initState();
getPrayerTime();
getPrayerTimeNextDay();
}
and here's how Builder widget Looks like:
#override
Widget build(BuildContext context){
return SafeArea(
child: Scaffold(
body: Builder(
builder: (context){
return Container();
},
),
)
);
}
Related
I am having trouble with the bool value. My bool value returns true only.
I have five buttons which set the state for the bool and time for fasting.
ElevatedButton(
onPressed: () async {
final SharedPreferences prefs = await _prefs;
playLocalAsset(0);
if((isFasting = true) && (widget.isFasting = true)) {
showError();
removeHours(fastDurs);
setState(() {
isFasting = false;
widget.isFasting = false;
});
//showAlerts();
} else {
setState(() {
isFasting = true;
widget.isFasting = true;
fastDuration = 16;
sixteen = 16;
eighteen = null;
twenty= null;
twentytwo = null;
twentyfour = null;
widget.fastDuration= 16;
endTime = startTime.add(Duration(hours: fastDuration!));
endTimeS = DateFormat('y/M/d, hh:mma').format(endTime);
_textLine = prefs
.setString('formattedDate', endTimeS)
.then((value) => (prefs
.getString('formattedDate') ??
Languages.of(context)!.setYourFastTime +'\n'+ startTimeS));
textDate = prefs.setString('eatTime', Languages.of(context)!.youWillEatAt)
.then((value) => (prefs.getString('eatTime') ?? ''));
showMessage(Languages.of(context)!.yourFastTimeIsSet);
updateHours(16);
});
}
},
child: Text('16:8', style: Constants.textTitleStyle),
style: Constants.buttonStyle),
const SizedBox(width:170),
ElevatedButton(
onPressed: () async {
final SharedPreferences prefs = await _prefs;
playLocalAsset(0);
if ((isFasting = true) && (widget.isFasting = true)) {
showError();
removeHours(fastDurs);
setState(() {
isFasting = false;
widget.isFasting = false;
});
//showAlerts();
} else {
setState(() {
isFasting = true;
widget.isFasting = true;
fastDuration = 18;
eighteen = 18;
sixteen = null;
twenty= null;
twentytwo = null;
twentyfour = null;
widget.fastDuration = 18;
endTime = startTime.add(Duration(hours: fastDuration!));
endTimeS = DateFormat('y/M/d, hh:mma').format(endTime);
_textLine = prefs
.setString('formattedDate', endTimeS)
.then((value) =>
(prefs
.getString('formattedDate') ??
Languages.of(context)!.setYourFastTime + '\n' + startTimeS));
textDate =
prefs.setString('eatTime', Languages.of(context)!.youWillEatAt)
.then((value) => (prefs.getString('eatTime') ?? ''));
showMessage(Languages.of(context)!.yourFastTimeIsSet);
updateHours(18);
});
}
showNotificationOneTime(context,
startTime.add(const Duration(hours: 14)).hour,
startTime.add(const Duration(minutes: 0)).minute);
showNotif(context,
endTime.hour, endTime.minute);},
child: Text('18:6', style: Constants.textTitleStyle),
style: Constants.buttonStyle
),
i declare my isFasting bool as nullable, then in init I check for the time, and if it is before the endTime then bool isFasting = true. As such:
#override
void initState() {
super.initState();
String startTimeS = DateFormat('y/M/d, hh:mma').format(startTime);
String endTimeS = DateFormat('y/M/d, hh:mma').format(endTime);
_textLine = _prefs.then((SharedPreferences prefs) {
String? fastEndTime = prefs.getString('formattedDate');
if ((fastEndTime != null) && (endTime
.isAfter(DateFormat('y/M/d, hh:mma').parse(fastEndTime)))) {
setState(() {
isFasting = false;
widget.isFasting = false;
});
return Languages.of(context)!.yourFastTimeFinished +"\n"+ endTimeS;
}
if (isFasting = false) {
return Languages.of(context)!.setYourFastTime +"\n"+ startTimeS;
}
if ((fastEndTime != null) && (endTime
.isBefore(DateFormat('y/M/d, hh:mma').parse(fastEndTime)))){
setState(() {
isFasting = true;
widget.isFasting = true;
});
}
return fastEndTime ??
Languages.of(context)!.setYourFastTime + "\n" + startTimeS;
});
textDate = _prefs.then((SharedPreferences prefs) {
String? stillFastingTime = prefs.getString('eatTime');
String? fastEndTime = prefs.getString('formattedDate');
if ((fastEndTime != null) && (endTime
.isBefore(DateFormat('y/M/d, hh:mma').parse(fastEndTime)))) {
setState(() {
isFasting = true;
widget.isFasting = true;
});
return Languages.of(context)!.youWillEatAt;
}
return stillFastingTime ?? '';
});
}
so, if isFasting is true then fast is cancelled and isFasting set to false. then clicking on a diff button should set state as shown in else condition. However, my isFasting is always true. it does not turn off... And it does not remove the previous hours, and it does not change the string of the text according to state. How do I make that bool value work properly? Thank you for your help!
use == instead of = when checking for equality:
if (isFasting = false) to if (isFasting == false)
and
if((isFasting = true) && (widget.isFasting = true)) to if(isFasting == true && widget.isFasting == true) also the braces here can be removed.
!= is correct here
I had this list but since i add lazy loading function,my sorting fuction stoped working.
here is some of the code and sort function is on top:
I had this list but since i add lazy loading function,my sorting fuction stoped working.
here is some of the code and sort function is on top:
I had this list but since i add lazy loading function,my sorting fuction stoped working.
here is some of the code and sort function is on top:
void showEvsePanels() async{
tempEvses.sort((a, b) {
int nameComp = a.sort_availability.compareTo(b.sort_availability);
if (nameComp == stationAvailability.available.index) {
return a.distance.compareTo(b.distance); // '-' for descending
}
return nameComp;
});
setState(() {
if (evseSearchField.isEmpty){
int i = 0;
if (tempEvses.length != 0){
evsePanels.clear();
while (i < tempEvses.length){
evsePanels.add(new EvsePanel(tempEvses[i], widget.appController, false));
i++;
}
}
}
else{
int i = 0;
if (tempEvses.length != 0){
evsePanels.clear();
while (i < tempEvses.length){
if (containsIgnoreCase(tempEvses[i].friendlyName, evseSearchField))
evsePanels.add(new EvsePanel(
tempEvses[i], widget.appController, false));
i++;
}
}
}
});
}
List<Evse> tempEvses = [];
Future fetch() async {
if (isLoading) return;
isLoading = true;
const limit = 10;
final url = Uri.parse('https://everywhere-dev.iccs.gr:18083/evse/getEvsesPaged?page=$page&pageLimit=$limit');
final response = await http.get(url);
if (response.statusCode == 200) {
final List newItems = json.decode(response.body)["results"];
setState(() {
page++;
isLoading = false;
if (newItems.length <limit) {
hasMore = false;
}
tempEvses.addAll(newItems.map<Evse>((items) {
final evseID = items['evseID'];
final friendlyName = items['friendlyName'];
final street = items['street'];
final streetNumber = items['streetNumber'];
final region = items['region'];
final lat = items['lat'] ?? 0.0;
final lng = items['lng'] ?? 0.0;
final connectorList = items['connectorList'];
final cpSerial = items['cpSerial'];
final img = items['img'];
return new Evse(evseID: evseID, friendlyName: friendlyName, street: street, streetNumber: streetNumber, region: region, lat: lat, lng: lng, connectorList: [connectorList], cpSerial: cpSerial, img: img);
}).toList());
for(int i=0 ; i<tempEvses.length; i++ ){
this.tempEvses[i].calculateDistance(widget.appController.currentLocation);
// this.tempEvses[i].calculateAvailability();
this.tempEvses[i].isEvseFavorite(widget.appController.favoritesList);
this.tempEvses[i].storePlugCounters();
}
showEvsePanels();
});
}
}
I have few widgets on home screen, one of them is there only if user save some data, from that moment
I want to count 7 days and if nothing else happen widget will be deleted.
I tried something like this:
//When user save data to widget
_saveTime() async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setString(
'StoreTime', DateTime.now().add(Duration(days: 8)).toString());
}
Then in the Home page
...
bool _thirdMenu;
String _difDays = '';
#override
initState() {
super.initState();
_thirdMenu = true;
WidgetsBinding.instance.addObserver(this);
_init();
}
_init() async {
SharedPreferences pref = await SharedPreferences.getInstance();
String oldTimePref = pref.getString('StoreTime') ?? '1969-07-20 20:18:04Z';
DateTime oldTime = DateTime.parse(oldTimePref);
DateTime newTime = DateTime.now();
var difference = oldTime.difference(newTime);
if (difference.inDays > 0) {
setState(() {
_thirdMenu = true;
_difDays = difference.inDays.toString();
});
} else {
setState(() {
_thirdMenu = false;
});
}
}
Not working, time stay the same and widget still showing...
If you want to work with days, I think you can work without hours and minutes.
You can isolate the days and check without using time difference.
int oldDay = oldTime.day;
int today = newTime.day;
if(today - oldDay >= 7) {
setState(() {
_thirdMenu = false;
});
} else {
setState(() {
_thirdMenu = true;
});
}
I have the following class which pulls in data from a remote JSON source, if I hardcode the URL into the class (daUrl) then it works just great.
But I am planning to use a variable URL which I want to feed into this class when I call it. But declaring the variable at the top just doesn't work.
Any ideas?
class ThreadData with ChangeNotifier
{
Map<String,dynamic> _map = {};
bool _error = false;
String _errorMessage = '';
int _isLoggedIn = 0;
int tid = 1836392;
Map<String,dynamic> get map => _map;
bool get error => _error;
String get errorMessage => _errorMessage;
int get isLoggedIn => _isLoggedIn;
//var daUrl = 'https://jsonplaceholder.typicode.com/todos/';
Future<void> get fetchData async {
final response = await post(Uri.parse(daUrl));
if ((response.statusCode == 200) && (response.body.length >0))
{
try
{
debugPrint('\Thread => Make Call => Success\n');
_map = json.decode(response.body);
_error = false;
}
catch(e)
{
_error = true;
_errorMessage = e.toString();
_map = {};
_isLoggedIn = 0;
}
}
else
{
_error = true;
_errorMessage = 'Error: It could be your internet connection';
_map = {};
_isLoggedIn = 0;
}
notifyListeners(); // if good or bad we will notify the listeners either way
}
void initialValues()
{
_map = {};
_error = false;
_errorMessage = '';
_isLoggedIn = 0;
notifyListeners();
}
}
You can pass it to its constructor:
class ThreadData with ChangeNotifier {
final String url;
// Defaults to some URL if not passed as parameter
ThreadData({this.url = 'https://jsonplaceholder.typicode.com/todos/'});
Map<String,dynamic> _map = {};
bool _error = false;
String _errorMessage = '';
int _isLoggedIn = 0;
int tid = 1836392;
Map<String,dynamic> get map => _map;
bool get error => _error;
String get errorMessage => _errorMessage;
int get isLoggedIn => _isLoggedIn;
Future<void> get fetchData async {
// Access the URL field here
final response = await post(Uri.parse(this.url));
if ((response.statusCode == 200) && (response.body.length >0))
{
try
{
debugPrint('\Thread => Make Call => Success\n');
_map = json.decode(response.body);
_error = false;
}
catch(e)
{
_error = true;
_errorMessage = e.toString();
_map = {};
_isLoggedIn = 0;
}
}
else
{
_error = true;
_errorMessage = 'Error: It could be your internet connection';
_map = {};
_isLoggedIn = 0;
}
notifyListeners(); // if good or bad we will notify the listeners either way
}
void initialValues()
{
_map = {};
_error = false;
_errorMessage = '';
_isLoggedIn = 0;
notifyListeners();
}
}
Then you can call it like that:
ThreadData(); // the URL will be https://jsonplaceholder.typicode.com/todos/
ThreadData(url: 'https://example.com'); // the URL will be https://example.com
I tried to save duration with sharedpreference only if my last duration is superior to the current duration and so show the MAX duration. my problem is that I don't know how to compare two string duration.
here is the code thanks (#ZeRj)
load_lastPressString()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
final lastPressString = prefs.getString("lastButtonPress");
_lastButtonPress = lastPressString!=null ? DateTime.parse(lastPressString) : DateTime.now();
_updateTimer();
_ticker = Timer.periodic(Duration(seconds:1),(_)=>_updateTimer());
});
}
save_lastPressString()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
prefs.setString('_lastButtonPress', _lastButtonPress.toIso8601String());
});
}
void _updateTimer() {
final duration = DateTime.now().difference(_lastButtonPress);
final newDuration = _formatDuration(duration);
setState(() {
_pressDuration = newDuration;
});
}
String _formatDuration(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inDays)}:${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
I tried the code bellow, but I can't use > with string and tried to parse int but not possible with date, and I tried to extract each decimal with regex but it's to complicated and I have errors I havn't understand.
save_max_lastPress()async{
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
if(_lastButtonPress>Max_lastButtonPress)
{
prefs.setString('_max_lastPress', Max_lastButtonPress) ;
}
}
);
}
For that you have to save the maximal as the duration.
Use prefs.setInt("maxDuration",maxDuration.toSeconds()) to save it as a int in shared preferences and load it with
Duration(seconds: prefs.getInt("maxDuration")
You can simply compare two instances of Duration.
I edited the last example to implement this feature:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutterfly/SharedPrefs.dart';
import 'package:flutterfly/SharedPrefs.dart' as prefix0;
class TestWidget extends StatefulWidget {
#override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
DateTime _lastButtonPress;
String _pressDuration;
Timer _ticker;
Duration _maxDuration;
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Time since button pressed"),
Text(_pressDuration),
Text("Maximal Duration"),
Text(_formatDuration(_maxDuration)),
RaisedButton(
child: Text("Press me"),
onPressed: () {
_lastButtonPress = DateTime.now();
_updateTimer();
sharedPreferences.setString("lastButtonPress",_lastButtonPress.toIso8601String());
},
)
],
),
);
}
#override
void initState() {
super.initState();
//load max duration, if there is none start with 0
_maxDuration = Duration(seconds:sharedPreferences.getInt("maxDuration")??0);
final lastPressString = sharedPreferences.getString("lastButtonPress");
_lastButtonPress = lastPressString!=null ? DateTime.parse(lastPressString) : DateTime.now();
_updateTimer();
_ticker = Timer.periodic(Duration(seconds:1),(_)=>_updateTimer());
}
#override
void dispose() {
_ticker.cancel();
super.dispose();
}
void _updateTimer() {
final duration = DateTime.now().difference(_lastButtonPress);
//check for new max duration here
Duration newMaxDuration = _maxDuration;
if(duration> _maxDuration) {
//save when current duration is a new max
newMaxDuration = duration;
sharedPreferences.setInt("maxDuration",newMaxDuration.inSeconds);
}
final newDuration =_formatDuration(duration);
setState(() {
_maxDuration = newMaxDuration;
_pressDuration = newDuration;
});
}
String _formatDuration(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
}