英文:
flutter - Variable that changed the value using sharedPreferences does not work properly -Has a simple example code
问题
I created a button that allows users to change the size of letters.
I hope that the font size value will remain changed even if I run the app again.
But in my code, it goes back to its original state. I made a simple code of the problem I faced. I made three files.
1.HomePage.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import './main.dart';
import './count_page.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late CountPage _countPage;
@override
Widget build(BuildContext context) {
String prefsFont = "prefs_font";
_countPage = Provider.of<CountPage>(context, listen: true);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text('Test_Code'),
centerTitle: true,
elevation: 0.0,
),
body: Container(
color: Colors.white,
child: Text('Font_size', style: TextStyle(fontSize: _countPage.font)),
),
bottomNavigationBar: BottomAppBar(
color: Colors.lime,
child: Container(
height: 200,
child: Row(
children: [
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 10);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40);
});
},
icon: Icon(Icons.looks_one_outlined),
),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 40);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40);
});
},
icon: Icon(Icons.looks_two_outlined),
),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 80);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40);
});
},
icon: Icon(Icons.looks_3_outlined),
),
],
),
),
),
);
}
}
2.main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import './HomePage.dart';
import 'count_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}
3.count_page.dart
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CountPage extends ChangeNotifier {
double _font = 40;
double get font => _font;
set font(double font) {
_font = font;
}
}
The value changes when you press the button, but it goes back to the original state when you run the app again. What is the problem?
英文:
I created a button that allows users to change the size of letters.
I hope that the font size value will remain changed even if I run the app again.
But in my code, it goes back to its original state.I made a simple code of the problem I faced. I made three files.
1.HomePage.dart
import 'dart:async';
import 'dart:convert';
// import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import './main.dart';
import './count_page.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late CountPage _countPage;
@override
Widget build(BuildContext context) {
String prefsFont = "prefs_font";
_countPage = Provider.of<CountPage>(context, listen: true);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text('Test_Code'),
centerTitle: true, // 중앙 정렬
elevation: 0.0,
),
body: Container(
color: Colors.white,
child: Text('Font_size',style: TextStyle(fontSize: _countPage.font),),
),
bottomNavigationBar: BottomAppBar(
color: Colors.lime,
child: Container(
height: 200,
child: Row(
children: [
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 10);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40) ;
});
},
icon: Icon(Icons.looks_one_outlined)),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 40);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40) ;
});
},
icon: Icon(Icons.looks_two_outlined)),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble('prefs_font', 80);
setState(() {
_countPage.font = (prefs.getDouble('prefs_font') ?? 40) ;
});
},
icon: Icon(Icons.looks_3_outlined)),
],
),
),
),
);
}
}
2.main.dart
import 'dart:convert';
// import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import './HomePage.dart';
import 'count_page.dart';
void main() {
// WidgetsFlutterBinding.ensureInitialized();
// MobileAds.instance.initialize();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}
3.count_page.dart
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CountPage extends ChangeNotifier {
double _font = 40;
double get font => _font;
set font(double font) {
_font = font;
}
}
I made it small so that the composition is similar to the project I am working on.
The value changes even if you press the button, but it goes back to the beginning when you run the app again.
What is the problem?
答案1
得分: 2
这里的基本情况是,你只是将字体存储在你的SharedPreference
中。但是当应用程序启动时,你没有取回它。你的CountPage
类没有存储字体大小。它是共享偏好存储了它。因此,你只需在应用程序启动时从SharedPreference
中获取数据,然后在你的代码中使用它。一个小例子将是:
- 初始化
SharedPreference
以便以后使用。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPref = await SharedPreferences.getInstance(); // 将会创建一个实例。
runApp(const MyApp());
}
- 然后使你的类默认使用
SharedPreference
实例。
class CountPage extends ChangeNotifier {
final SharedPreferences pref;
CountPage({required this.pref});
double get font => pref.getDouble('prefs_font') ?? 40;
setFont(double font) async {
await pref.setDouble('prefs_font', font);
notifyListeners(); // 这是必需的,以便当值更改时,UI会得到更新。
}
}
- 然后将
SharedPreference
实例传递给该类,以便它可以使用它。
class MyApp extends StatelessWidget {
final SharedPreferences pref;
const MyApp({Key? key, required this.pref}) : super(key: key); // 从主函数获取实例。
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage(pref: pref), // 传递实例。
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}
另外,在你的保存按钮上,看起来你正在使用getter来设置值,这不应该起作用。但现在你可以这样调用它:
onPressed: () async {
setState(() { // 现在这个setState是可选的,因为你告诉通知器在设置值时通知其监听器。
await _countPage.setFont(/*此按钮的字体大小*/);
});
}
英文:
So basically what's happening here is, you're only storing the font inside your SharedPrefrence
. But you're not fetching it back when the app starts. Your CountPage
class isn't storing the font size. It's shared preference that's storing it. So you have to just fetch the data from SharedPrefrence
on the app start. And then use it in your code. A small example will be
- Initialize
SharedPrefrence
so you can use later.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPref = await SharedPrefrence.getInstance(); // Instance will be created.
runApp(const MyApp());
}
2.Then make your class use SharedPrefrence
instance by default
class CountPage extends ChangeNotifier {
final SharedPrefrence pref;
CountPage({required this.pref});
double get font => pref.getDouble('prefs_font') ?? 40;
setFont(double font) async {
await prefs.setDouble('prefs_font', font);
notifyListeners(); //This is necessary so that when the value changes the UI gets an update.
}
}
- Then pass the
SharedPrefrence
instance to that class, so it can use it.
class MyApp extends StatelessWidget {
final SharedPrefrence pref;
const MyApp({Key? key, required this.pref}) : super(key: key); // Getting the instance from main.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage({pref: pref}),//Passing the instance.
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}
Also on your save button it looks like you're using a getter to set the value, which shouldn't work. But now you can just call it like this
onPressed: () async {
setState(() { // Now this setState is optional bcz you're saying the notifier to notify it's listeners, whenever you're setting the value.
await _countPage.setFont(\* font size for this button */);
});
},
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论