How to persist value from range slider in shared preferences? - flutter

I need to persist value from range slider to shared preferences, when user leaves page with sliders, it will still save value, not without resetting to default settings (default is 1).
I am trying to make things like that:
#override
void initState() {
// _loadSlider();
super.initState();
}
#override
void dispose() {
_debounce?.cancel();
super.dispose();
}
var _currentRangeValues = const RangeValues(1, 16);
void _loadSlider() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_currentRangeValues = (prefs.getStringList('sliderGain') ??
[
_currentRangeValues.start.round().toString(),
_currentRangeValues.end.toString()
]) as RangeValues;
});
}
// change slider value to value
void _changeSlider(RangeValues value) {
setState(() {
_currentRangeValues = value;
});
}
// store slider value
void _storeSlider() async {
final prefs = await SharedPreferences.getInstance();
prefs.setStringList('sliderGain', [
_currentRangeValues.start.round().toString(),
_currentRangeValues.end.round().toString()
]);
}
But I'm getting an error
RangeValues is not subtype of type List
How to resolve this issue?

I found what the issue was about my slider and attempts to save data from it to sharedprefernces. So it needs to convert to List after declaring the range value variable. After that, I made small changes in the code and put data from the declared list into the get string, and after that everything worked. Thanks to the previous commenter for the tip.
void _loadSlider() async {
final prefs = await SharedPreferences.getInstance();
List<String> valuesString = [currentRange.start.round().toString(), currentRange.end.round().toString() ];
setState(() {
valuesString = (prefs.getStringList('sliderGain') ??
[
valuesString.toString()
]);
print(valuesString);
});
}

Related

Cannot pass data to bottom navbar page - flutter

I have a home page called home.dart, where I have defined my other pages like so (I'm using a bottom navbar):
`
late final List<Widget> _pageOptions;
#override
void initState() {
appBarColor = colors[4];
initializeCoins();
_pageOptions = [
ProScreen(Values.coins.toString()),
CatScreen(),
NotScreen(),
FavScreen(),
HomeScreen(),
];
super.initState();
}
`
I'm receiving some data from an API and showing it in home.dart's appBar and it works fine. the thing is when I'm trying to show the same thing in ProScreen (passing the same variable I'm showing in appbar to ProScreen's constructor) it doesn't work and shows it's defaut values instead (0)
What should I do?
class Values{
static int coins = 0;
...
}
Future<void> initializeCoins() async {
_prefs =await SharedPreferences.getInstance();
var response = await http.get(Uri.parse(Values.url+Values.user_endpoint),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${_prefs?.getString('token')}',
}
);
setState(() {
coinsLoaded = true;
Values.coins = (jsonDecode(response.body)['user']['score']);
});
}
I think this should work
Create a async function that prepare pages (initPages), it will wait until Values initialize, and after that do a setState and create your pages
Like this:
late final List<Widget> _pageOptions;
#override
void initState() {
initPages();
super.initState();
}
initPages() async {
appBarColor = colors[4];
await initializeCoins();
setState(() {
_pageOptions = [
ProScreen(Values.coins.toString()),
CatScreen(),
NotScreen(),
FavScreen(),
HomeScreen(),
];
});
}
That's because you're passing different value than you think. When you download data it works correctly the first time because you're using data received, but when creating new screen you take static value that you've created previously which is 0.
You explicitly state that this is a new 'instance' of the class Values when doing Values.coins.toString().
Try returning int that you're receiving Future<int> initializeCoins() async { and return jsonDecode(response.body)['user']['score']. With this you can do something like that:
#override
void initState() async {
appBarColor = colors[4];
int coins = await initializeCoins();
_pageOptions = [
ProScreen(coins.toString()),
CatScreen(),
NotScreen(),
FavScreen(),
HomeScreen(),
];
super.initState();
}

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 {
// …
}
}

How to save a list with SharedPreferences?

I tried to save a List (which is called test)with two variables with SharedPreferences. I tried the code below, but I get some errors. Does anybody see the mistake i made? (I think it´s kind of an easy to fix mistake, but I´m a beginner and can´t find it ;)
int counter1 = 0;
int counter2 = 20;
String nameKey = "eins";
var test = [counter1, counter2];
#override
void initState() {
super.initState();
}
Future<bool> save() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return await preferences.setIntList(nameKey, test);
}
Future<List<int>> load() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getIntList(nameKey);
}
set() {
load().then((value) {
setState(() {
test = value;
});
});
}
Thanks in advance :)
Future<List<String>> load() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getStringList(nameKey);
}

Why can´t I save int with shared_preferences?

I tried to build a simple application, which shoul save and output a value whith shared_preferences. I tried to save an int, but it doesnt´t work. It could be, that the mistake is because of I tried to "convert" the code a youtuber did with a String instead of an int. Can anybody find my mistake? Below is the change code I tried.
int lastLoginInt = 1;
String nameKey = "_key_name";
#override
void initState() {
super.initState();
}
Future<bool> saveLastLoginInt() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return await preferences.setInt(nameKey, lastLoginInt);
}
Future<int> loadLastLoginInt() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getInt(nameKey);
}
setLastLoginInt() {
loadLastLoginInt().then((value) {
setState(() {
lastLoginInt = value;
});
});
}
You are not calling functions.
Probably you should do this at your initState() function..like this..
#override
void initState() {
super.initState();
saveLastLoginInt();
}
Then use setLastLoginInt() where needed.

How to init state of widget variable with Future string in flutter

I have to initialise the state of widget variable with the value stored in StoredProcedure.
void initState() {
widget.query = fetchMake();
super.initState();
}
Future<String> fetchMake() async{
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
query.toString();
}
But the issue is that it cant assign that value to query variable and showing error value to type future string cannot assign to string flutter
How can I do that?
fetchMake is async so you have to put await where you call that method but it will not work because you are calling it in initState.
So You have to assign widget.query variable value in that function only. Moreover, as you get data you have to call setState, so data you receive reflect in ui.
In addition to that you have to check query is null or not where you are using it because when first time build method call it will not have any data.
String query;
void initState() {
fetchMake();
super.initState();
}
fetchMake() async{
final prefs = await SharedPreferences.getInstance();
setState((){
query = prefs.getString(key) ?? 'default';
});
}
You can try:
String query;
void initState() {
super.initState();
fetchMake().then((value) {
setState(() {
query = value;
});
});
}
Future<String> fetchMake() async{
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
}
1, You can not set state with widget.query.
2, Create a variable query on state of Widget.
3, fetchMake is a async function => using then to wait result.