flutter – Variable that changed the value using sharedPreferences does not work properly -Has a simple example code

huangapple go评论53阅读模式
英文:

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 &#39;dart:async&#39;;
import &#39;dart:convert&#39;;
// import &#39;package:google_mobile_ads/google_mobile_ads.dart&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;package:flutter/services.dart&#39;;
import &#39;package:provider/provider.dart&#39;;
import &#39;package:shared_preferences/shared_preferences.dart&#39;;
import &#39;./main.dart&#39;;
import &#39;./count_page.dart&#39;;
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State&lt;HomePage&gt; createState() =&gt; _HomePageState();
}
class _HomePageState extends State&lt;HomePage&gt; {
late CountPage _countPage;
@override
Widget build(BuildContext context) {
String prefsFont = &quot;prefs_font&quot;;
_countPage = Provider.of&lt;CountPage&gt;(context, listen: true);
return  Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text(&#39;Test_Code&#39;),
centerTitle: true, // 중앙 정렬
elevation: 0.0,
),
body: Container(
color: Colors.white,
child: Text(&#39;Font_size&#39;,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(&#39;prefs_font&#39;, 10);
setState(() {
_countPage.font = (prefs.getDouble(&#39;prefs_font&#39;) ?? 40) ;
});
},
icon: Icon(Icons.looks_one_outlined)),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble(&#39;prefs_font&#39;, 40);
setState(() {
_countPage.font = (prefs.getDouble(&#39;prefs_font&#39;) ?? 40) ;
});
},
icon: Icon(Icons.looks_two_outlined)),
IconButton(
onPressed: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble(&#39;prefs_font&#39;, 80);
setState(() {
_countPage.font = (prefs.getDouble(&#39;prefs_font&#39;) ?? 40) ;
});
},
icon: Icon(Icons.looks_3_outlined)),
],
),
),
),
);
}
}

2.main.dart

import &#39;dart:convert&#39;;
// import &#39;package:google_mobile_ads/google_mobile_ads.dart&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;package:flutter/services.dart&#39;;
import &#39;package:provider/provider.dart&#39;;
import &#39;package:shared_preferences/shared_preferences.dart&#39;;
import &#39;./HomePage.dart&#39;;
import &#39;count_page.dart&#39;;
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) =&gt; CountPage(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: HomePage(),
),
);
}
}

3.count_page.dart

import &#39;dart:ui&#39;;
import &#39;package:flutter/cupertino.dart&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;package:shared_preferences/shared_preferences.dart&#39;;
class CountPage extends ChangeNotifier {
double _font = 40;
double get font =&gt; _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中获取数据,然后在你的代码中使用它。一个小例子将是:

  1. 初始化SharedPreference以便以后使用。
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final sharedPref = await SharedPreferences.getInstance(); // 将会创建一个实例。

  runApp(const MyApp());
}
  1. 然后使你的类默认使用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会得到更新。
  }
}
  1. 然后将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

  1. 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 =&gt; pref.getDouble(&#39;prefs_font&#39;) ?? 40;
  setFont(double font) async {
    await prefs.setDouble(&#39;prefs_font&#39;, font);
    notifyListeners(); //This is necessary so that when the value changes the UI gets an update.
  }

}
  1. 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) =&gt; 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&#39;re saying the notifier to notify it&#39;s listeners, whenever you&#39;re setting the value.
await _countPage.setFont(\* font size for this button */);
});
                  },

huangapple
  • 本文由 发表于 2023年2月18日 21:00:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493502.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定