You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

页面刷新后保留数组ID并新增ID的技术实现问询

Flutter 解决Checkbox选中状态持久化及ID重复添加问题

核心问题

你当前的代码存在两个关键问题:

  • multipleSelected是局部变量,每次页面刷新(比如调用setState、热重载)都会重新初始化为空数组,导致已选数据丢失。
  • ID检查逻辑绕了弯路,遍历baseNames的写法不符合需求,应该直接针对选中的ID做存在性判断。

解决方案

1. 用SharedPreferences做本地持久化

把已选ID数组存在本地存储,页面初始化时读取,修改后立即保存,确保刷新后数据不丢失。

2. 修正ID选择逻辑

直接判断当前ID是否在已选数组中,根据选中状态添加或移除,同时同步到本地。

3. 同步Checkbox初始状态

页面加载完成后,根据本地存储的已选ID,更新baseNames里的isCheked字段,让Checkbox显示正确的初始状态。

完整代码示例

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class CategorySelectPage extends StatefulWidget {
  const CategorySelectPage({super.key});

  @override
  State<CategorySelectPage> createState() => _CategorySelectPageState();
}

class _CategorySelectPageState extends State<CategorySelectPage> {
  // 已选ID数组,从本地读取初始化
  List<String> multipleSelected = [];
  // 从API获取的原始数据
  List<Map<String, dynamic>> baseNames = [];

  @override
  void initState() {
    super.initState();
    // 页面初始化时读取本地存储的已选ID
    _loadSelectedIds();
    // 替换成你的API请求逻辑
    _fetchBaseData();
  }

  // 从本地加载已选ID
  Future<void> _loadSelectedIds() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      multipleSelected = prefs.getStringList('selected_ids') ?? [];
    });
    // 同步Checkbox状态
    _syncCheckboxStatus();
  }

  // 模拟API获取baseNames数据
  Future<void> _fetchBaseData() async {
    // 实际开发中替换为真实API请求
    await Future.delayed(const Duration(seconds: 1));
    setState(() {
      baseNames = [
        {'id': '1', 'name': '分类A', 'isCheked': false},
        {'id': '2', 'name': '分类B', 'isCheked': false},
        {'id': '3', 'name': '分类C', 'isCheked': false},
      ];
    });
    // API数据加载后同步Checkbox状态
    _syncCheckboxStatus();
  }

  // 同步已选ID和Checkbox状态
  void _syncCheckboxStatus() {
    if (baseNames.isEmpty) return;
    setState(() {
      for (var item in baseNames) {
        item['isCheked'] = multipleSelected.contains(item['id']);
      }
    });
  }

  // 处理分类选择逻辑
  Future<void> _onCategorySelected(bool selected, String id) async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      if (selected) {
        // 检查ID是否已存在,不存在则添加
        if (!multipleSelected.contains(id)) {
          multipleSelected.add(id);
        }
      } else {
        // 移除选中的ID
        multipleSelected.remove(id);
      }
    });
    // 保存到本地存储
    await prefs.setStringList('selected_ids', multipleSelected);
    // 同步Checkbox状态
    _syncCheckboxStatus();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('分类选择')),
      body: ListView.builder(
        itemCount: baseNames.length,
        itemBuilder: (context, i) {
          return ListTile(
            title: Text(baseNames[i]['name']),
            trailing: Checkbox(
              activeColor: Colors.green,
              tristate: true,
              checkColor: Colors.green,
              side: const BorderSide(width: 2, color: Colors.white),
              value: baseNames[i]['isCheked'],
              onChanged: (bool? selected) {
                setState(() {
                  _onCategorySelected(selected ?? false, baseNames[i]['id']);
                });
              },
            ),
          );
        },
      ),
    );
  }
}

代码说明

  • 初始化时通过_loadSelectedIds读取本地存储的已选ID,彻底解决页面刷新后数据丢失的问题。
  • _onCategorySelected方法直接判断ID是否存在,严格符合你“不存在才添加”的需求,操作后立即同步到本地存储。
  • _syncCheckboxStatus方法确保Checkbox的状态始终和已选ID数组保持一致,不管是页面初始化还是修改选择后。

内容的提问来源于stack exchange,提问作者user16357470

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:25:19