Flutter中SharedPreferences获取布尔值始终返回true问题
问题分析与解决方案
核心问题
你所有的Person实例都共用了同一个SharedPreferences键"Person['Joined']"——只要有一个Person被设置为true,这个键的值就会被永久覆盖为true,后续不管数据库里新建的Person默认值是false,读取这个固定键得到的都是之前存的true。
解决步骤
1. 给每个Person分配唯一标识
确保你的Person数据库表有唯一字段(比如id),用这个字段生成专属的SharedPreferences键,避免不同实例互相干扰。
2. 修改首页的状态存储逻辑
把固定键改成带唯一标识的动态键:
Widget listItem({ required Map Person, }) { void savebool() async { SharedPreferences prefs = await SharedPreferences.getInstance(); // 用Person的id生成专属键,替换成你实际的唯一字段名 String uniqueKey = "person_${Person['id']}_joined"; await prefs.setBool(uniqueKey, Person['Joined']); print(Person['Joined']); } return Slidable( startActionPane: ActionPane( motion: const BehindMotion(), extentRatio: 1 / 5, children: [ SlidableAction( backgroundColor: Colors.blue, icon: Icons.add, label: 'Join', onPressed: (BuildContext context) { setState(() { Person['Joined'] = true; }); savebool(); }, ) ], ), // 其他代码... ); }
3. 修改Favourites.dart的状态读取逻辑
需要把当前Person的唯一标识传到Favourites页面,然后读取对应键的值:
// 先给Favourites页面添加Person参数 class Favourites extends StatefulWidget { final Map Person; const Favourites({super.key, required this.Person}); @override State<Favourites> createState() => _FavouritesState(); } class _FavouritesState extends State<Favourites> { late bool joined; @override void initState() { super.initState(); getPrefs(); } getPrefs() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String uniqueKey = "person_${widget.Person['id']}_joined"; setState(() { // 优先取本地存储的值,没有则用数据库默认值 joined = prefs.getBool(uniqueKey) ?? widget.Person['Joined']; print("getbool: $joined"); }); } // 其他代码... }
4. 列表项初始化时同步本地状态
在首页的列表项初始化时,要从对应键读取状态覆盖数据库默认值,保证显示和本地存储一致:
// 如果listItem是StatefulWidget,在initState里加载状态 @override void initState() { super.initState(); _loadJoinedState(); } void _loadJoinedState() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String uniqueKey = "person_${widget.Person['id']}_joined"; setState(() { widget.Person['Joined'] = prefs.getBool(uniqueKey) ?? widget.Person['Joined']; }); }
总结
通过给每个Person生成唯一的存储键,彻底解决了不同实例状态互相覆盖的问题。新创建的Person因为对应键不存在,会使用数据库默认的false值,不会再被旧的true值影响。
内容的提问来源于stack exchange,提问作者Tyrone
相关产品推荐
相关产品推荐

