How do I make Flutter Widget disappear after certain time (in days)? - flutter

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;
});
}

Related

Flutter TableCalendar . SharedPreferences

I want to save the table calendar data.
First of all, I succeeded in creating data for each date, but I don't know how to use sharedPreferences.
I don't know what it is even if I googled it and applied it in various ways.
https://medium.flutterdevs.com/display-dynamic-events-at-calendar-in-flutter-22b69b29daf6
I think the code that's closest to the answer is this person's method
If you apply it and make some changes, you will encounter various bugs.
I spent almost a week on this for three hours. It's so hard that I just want to solve it today.
I have to work out, and I have a lot of other assignments
Because of the desire to keep solving this problem, it doesn't get out of the chair.
My personality is getting dirty after meeting a problem that hasn't been solved for a week.
I beg you.
class DiaryService extends ChangeNotifier {
DateTime focusedDay = DateTime.now();
DateTime selectedDay = DateTime.now();
TextEditingController createFieldController = TextEditingController();
TextEditingController updateFieldController = TextEditingController();
List<Diary> diaryList = [];
Map<DateTime, List<Diary>> diaryMap = {};
List<Diary> getByDate(DateTime date) {
return diaryMap[date] ?? [];
}
void create(String text, DateTime selectedDate) {
diaryList.add(Diary(text: text, createdAt: DateTime.now(), selectedDate:
selectedDate));
diaryMap[selectedDate] = diaryList.where((element) {
return element.selectedDate == selectedDate;
}).toList();
print(selectedDate.day);
notifyListeners();
}
void update(DateTime createdAt, String newContent) {
int t = diaryList.indexWhere((element) => element.createdAt == createdAt);
diaryList.removeWhere((element) => element.createdAt == createdAt);
diaryList.insert(t, Diary(text: newContent, createdAt: createdAt,
selectedDate: selectedDay));
addListInMap();
notifyListeners();
}
void delete(DateTime createdAt) {
diaryList.removeWhere((element) => element.createdAt == createdAt);
addListInMap();
print(getByDate);
print(diaryMap);
notifyListeners();
}
void addListInMap() {
diaryMap[selectedDay] = diaryList.where((element) => element.selectedDate
== selectedDay).toList();
}
void encodeData() async {
String dd = Diary.encode(diaryList);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("diaryList", dd);
notifyListeners();
}
Future<List<Diary>> decodeData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String getData = prefs.getString("diaryList") ?? "[]";
print(getData);
diaryList = Diary.decode(getData);
notifyListeners();
return diaryList;
}
}

How do i create a rounded search bar in flutter that also shows the recent searches from the search bar?

I have been wanting to find a solution to create a rounded search bar in flutter which also shows the list of recent searches underneath it. How is it possible to create the previous widget?
Using the package below, you can save the information you want to the device memory and then withdraw it from there (username, password, search history, etc.). The sample code is in the document.
https://pub.dev/packages/shared_preferences
like this:
void handleRememberMe(bool? value) {
_isChecked = value!;
SharedPreferences.getInstance().then(
(prefs) {
prefs.setBool("remember_me", value);
prefs.setString('userName', userNameController.text);
prefs.setString('password', passwordController.text);
},
);
setState(() {
_isChecked = value;
});
}
void loadUserEmailPassword() async {
try {
SharedPreferences _prefs = await SharedPreferences.getInstance();
var _email = _prefs.getString("userName") ?? "";
var password = _prefs.getString("password") ?? "";
var _remeberMe = _prefs.getBool("remember_me") ?? false;
if (_remeberMe) {
setState(() {
_isChecked = true;
});
userNameController.text = _email;
passwordController.text = password;
} else {
userNameController.text = "";
passwordController.text = "";
setState(() {
_isChecked = false;
});
}
} catch (e) {
debugPrint(e.toString());
}
}

Is there a way I could refactor these similar functions in dart?

I'm trying to set the state of the variables using provider state management in Flutter, so when I call the provider in my build, it's going to change the state of the booleans in my provider class.
The problem now is most of the function in the provider are doing basically the same thing, since they are just changing the value of the boolean to the opposite.
I've been looking for a way to make the code shorter since the functions are doing basically the same thing. I've been wrapping my head around the whole thing but I can't come up with anything, and having this spaghetti mess of code hurts my eyes:
class AlarmState extends ChangeNotifier {
var hour = 0;
var min = 0;
bool isWednesday = false;
bool isMonday = false;
bool isTuesday = false;
bool isThursday = false;
bool isFriday = false;
bool isSaturday = false;
bool isSunday = false;
bool alarmRing = false;
bool vibrate = false;
bool snooze = false;
List<AlarmObject> alarmList = [];
bool isAlarmOn = true;
void handleChangeHour(int index) {
hour = index;
notifyListeners();
}
void handleChangeMin(int index) {
min = index;
notifyListeners();
}
void changeMonday() {
isMonday = !isMonday;
notifyListeners();
}
void changeTuesday() {
isTuesday = !isTuesday;
notifyListeners();
}
void changeWednesday() {
isWednesday = !isWednesday;
notifyListeners();
}
void changeThursday() {
isThursday = !isThursday;
notifyListeners();
}
void changeFriday() {
isFriday = !isFriday;
notifyListeners();
}
void changeSaturday() {
isSaturday = !isSaturday;
notifyListeners();
}
void changeSunday() {
isSunday = !isSunday;
notifyListeners();
}
void handleAlarmRing(value) {
alarmRing = value;
notifyListeners();
}
void handleSnooze(value) {
snooze = value;
notifyListeners();
}
void handleVibrate(value) {
vibrate = value;
notifyListeners();
}
void handleIsAlarmOn(bool value) {
isAlarmOn = value;
print(isAlarmOn);
notifyListeners();
}
}
I recommend using an enum Weekday to represent the days, and using a Set<Weekday> to keep track of which days are active. Then, using a single function with optional named parameters to update the AlarmState.
The end result may look something like this:
enum Weekday {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday,
}
class AlarmState extends ChangeNotifier {
var hour = 0;
var min = 0;
Set<Weekday> activeDays = Set();
bool alarmRing = false;
bool vibrate = false;
bool snooze = false;
List<AlarmObject> alarmList = [];
bool isAlarmOn = true;
void update({
int? hour,
int? min,
Set<Weekday>? activeDays,
bool? alarmRing,
bool? vibrate,
bool? snooze,
bool? isAlarmOn,
}) {
this.hour = hour ?? this.hour;
this.min = min ?? this.min;
this.activeDays = activeDays ?? this.activeDays;
this.alarmRing = alarmRing ?? this.alarmRing;
this.vibrate = vibrate ?? this.vibrate;
this.snooze = snooze ?? this.snooze;
this.isAlarmOn = isAlarmOn ?? this.isAlarmOn;
notifyListeners();
}
}
So then, for a few examples of updating your alarm, it should look something like this:
final alarmState = AlarmState();
// Add monday, wednesday and friday
alarmState.update(
activeDays: alarmState.activeDays..addAll([
Weekday.monday,
Weekday.wednesday,
Weekday.friday,
]),
);
// Remove monday
alarmState.update(
activeDays: alarmState.activeDays..remove(Weekday.monday),
);
// Update hour and minute
alarmState.update(
hour: 12,
min: 30,
);
// Turn off the alarm
alarmState.update(
isAlarmOn: false,
);
// Check whether the alarm should go off on monday
final isActiveOnMonday = alarmState.activeDays.contains(Weekday.monday);

Change bool in initState flutter

I have a page with this code:
class _HomeScreenState extends State<HomeScreen> {
bool isFirstLoading = true;
#override
void initState() {
super.initState();
if (isFirstLoading) {
getInfo();
setState(() {
isFirstLoading = false;
});
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Loader.show(context,
isAppbarOverlay: true,
isBottomBarOverlay: true,
progressIndicator: CircularProgressIndicator());
var url = kLinkAPI + "/getInfo";
var response =
await http.post(url, headers: {"Content-Type": "application/json"});
var resObj = jsonDecode(response.body);
if (response != null) {
setState(() {
if (resObj.length > 0) {
address = resObj[0]['address'];
countryInfo = resObj[0]['country_info'];
phone = resObj[0]['phone'];
latitude = resObj[0]['latitude'];
longitude = resObj[0]['longitude'];
isFirstLoading = false;
prefs.setString('address', address);
prefs.setString('countryInfo', countryInfo);
prefs.setString('phone', phone);
prefs.setString('latitude', latitude);
prefs.setString('longitude', longitude);
}
});
}
Loader.hide();
}
void getInfoFromSharedPref() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
address = prefs.getString('address');
countryInfo = prefs.getString('countryInfo');
phone = prefs.getString('phone');
latitude = prefs.getString('latitude');
longitude = prefs.getString('longitude');
});
}
}
I would like to make sure that the first time I enter the page, the isFirstLoading variable is set to false and then calls the getInfo function with the http call while if it is false it takes from the shared preferences.
isFirstLoading is now always true
how could I solve?
I think you're overcomplicating your code. Let me know if this solves your issue.:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs;
#override
void initState() {
super.initState();
getInfo();
}
// ...
}
Now, the first time this widget is inserted into the tree:
initState() will be called once.
Therefore, getInfo() will be called. getInfo() will make the http call and update the prefs variable using setState, which you have already done.
Whenever the widget is reloaded, the prefs variable will not be lost since it is a stateful widget.
Next, if you would like to save the preference settings locally instead of making an http call every time the user opens the app, you should handle that inside of getInfo() itself. Something like this:
getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (prefs.getBool("isFirstLoading") == false) {
// setState to update prefs variable
} else {
// make http call
// save prefs (optional)
// setState to update prefs variable
}
}
If I undestand correctly, you are trying to only call the getInfo method on the first load, and the getInfoFromSharedPref all the other time.
My suggestion is to save the isFirstLoading bool as a preference like so:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLoading = prefs.getBool("isFirstLoading") ?? true;
#override
void initState() async {
super.initState();
if (isFirstLoading) {
await getInfo();
await prefs.setBool("isFirstLoading", false);
isFirstLoading = false;
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
// …
}
void getInfoFromSharedPref() async {
// …
}
}

type 'future<dynamic>' is not a subtype of type 'function'

when i run my app in debug mode it shows me the error "type 'future' is not a subtype of type 'function'" all over the screen and also in the debug console. Can someone help me? I imagine it's a problem with async functions "reset","rateoGet" and "rateoSave" but i can't find any solution.
P.S. I've deleted part of the code because it was useless for this question.
int plus;
int min;
int per;
int div;
double val;
int gameswon =0;
int moves;
static int mosse=15;
String win = "gioca";
int games=0;
double rateo=1;
String mode;
int flag;
var timer=30;
#override
void initState() {
super.initState();
reset();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body:
MyButton(text: "$per" ,color: Colors.deepPurpleAccent, onTap: (){
setState(() {
val*=per;
});
if(widget.mode=="timermode" && flag==0){
timerceckresults();
}else if(widget.mode=="movesmode"){
checkResult();
}
},
MyBottomButton(text: "Reset",color: Colors.indigo,width:160, onTap: reset()),
),
}
checkResult() {
if(val == 101) {
print("hai vinto");
win="Hai Vinto";
setState(() {});
gameswon++;
Timer(Duration(seconds: 2), () {
reset();
});
} else {
print("ci sei quasi");
moves++;
mosse--;
win="$mosse moves left";
setState(() {});
if(moves>14){
print("hai perso coglione");
win="Hai Perso Coglione";
setState(() {});
Timer(Duration(seconds: 2), () {
reset();
});
}
}
}
timerceckresults(){
flag=1;
timer = 30;
Timer.periodic(Duration(seconds: 1), (t){
timer--;
setState(() {
win = "${timer.toString()}seconds left";
});
if(val==101){
timer=0;
}
if(timer == 0) {
t.cancel();
if(val == 101) {
win="Hai Vinto";
setState(() {});
gameswon++;
Timer(Duration(seconds: 2), () {
reset();
});
} else {
win="Hai Perso Coglione";
setState(() {});
Timer(Duration(seconds: 2), () {
reset();
});
}
}
});
static int randNum(x,y) {
var rng = new Random();
return rng.nextInt(y-x)+x;
}
reset() async{
timer=1;
plus = randNum(4, 9);
min = randNum(5, 19);
per = randNum(3, 9);
div = randNum(2, 5);
val = randNum(2, 11).toDouble();
moves = 0;
mosse=15;
if(widget.mode=="timermode"){
win="start playing";
}else{
win="$mosse moves left";
}
await rateoSave();
await rateoGet();
games++;
rateo=gameswon/(games-1);
await rateoSave();
flag=0;
setState(() {});
}
rateoSave() async {
SharedPreferences prefs=await SharedPreferences.getInstance();
await prefs.setInt("games",games);
await prefs.setInt("gameswon",gameswon);
}
rateoGet() async {
SharedPreferences prefs=await SharedPreferences.getInstance();
games=(prefs.getInt("games") ?? 0);
gameswon=(prefs.getInt("gameswon") ?? 0);
https://dart.dev/codelabs/async-await read this before you check the answer will help you alot
reset() async{
timer=1;
plus = randNum(4, 9);
min = randNum(5, 19);
per = randNum(3, 9);
div = randNum(2, 5);
val = randNum(2, 11).toDouble();
moves = 0;
mosse=15;
if(widget.mode=="timermode"){
win="start playing";
}else{
win="$mosse moves left";
}
await rateoSave();
await rateoGet();
games++;
rateo=gameswon/(games-1);
await rateoSave();
flag=0;
setState(() {});
}
Future<bool> rateoSave() {
SharedPreferences prefs= SharedPreferences.getInstance();
prefs.setInt("games",games);
prefs.setInt("gameswon",gameswon);
return true;
}
Future<bool> rateoGet() async {
SharedPreferences prefs= SharedPreferences.getInstance();
await games=(prefs.getInt("games") ?? 0);
await gameswon=(prefs.getInt("gameswon") ?? 0);
return true;
}
you are trying to get a variable from a method that returns a future. you need to add await just before you make the call to that function.
can you tell us in which line this error occurs ?
The most important thing to keep in mind is that if anything in your call-chain returns a Future, everything above it must deal with futures, either by returning the future itself (if no processing must be done), or await'ing and dealing with the returned value (but you'll still be returning a future).