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

Flutter基于SharedPreferences切换页面异常:始终显示sports分类

问题分析与解决方案

核心问题

  • NewsScreen重复创建Cubit实例:NewsScreen中通过BlocProvider(create: (context) => NewsCubit()...)生成了全新的NewsCubit,与HomeScreen使用的Cubit完全隔离,新实例的catergorieModel为null,因此触发默认值'sports'。
  • Cubit初始化未读取缓存:应用启动时,NewsCubit没有主动从SharedPreferences加载保存的分类ID,导致初始状态无法匹配用户之前的选择。
  • onClick方法逻辑错误:当前onClick中保存的是this.catergorieModel!.id,但此时this.catergorieModel还未赋值,应该使用传入的参数catergorieModel的ID,且需先更新状态再保存缓存。

修复步骤

1. 共享全局Cubit,移除NewsScreen中的BlocProvider

确保整个应用使用同一个NewsCubit实例,建议在应用根节点(如MaterialApp外层)提供BlocProvider,修改NewsScreen直接复用已有Cubit:

class NewsScreen extends StatelessWidget {
  static const String routeName = 'news_screen';

  const NewsScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<NewsCubit, HomeState>(
      listener: (context, state) {
        if (state is HomeSorcesSuccessState) {
          NewsCubit.get(context).getNewsData();
        }
      },
      builder: (context, state) {
        var cubit = NewsCubit.get(context);
        if (state is HomeLoadindState) {
          return const Center(child: CircularProgressIndicator());
        } else if (state is HomeSorcesErrorState) {
          return const Center(child: Text('No News'));
        }
        return Column(
          children: [
            const TabBarWidget(),
            Expanded(
              child: ListView.builder(
                itemCount: cubit.articlesList.length,
                itemBuilder: (context, index) {
                  return ArticlesNewsWidget(
                    articles: cubit.articlesList[index],
                  );
                },
              ),
            )
          ],
        );
      },
    );
  }
}

2. 在NewsCubit初始化时加载缓存

修改NewsCubit构造函数,启动时自动读取SharedPreferences中的分类ID并更新状态:

class NewsCubit extends Cubit<HomeState> {
  NewsCubit() : super(HomeInitialState()) {
    _loadSavedCategory();
  }

  // 假设categories列表在Cubit中可访问,或通过参数传入
  List<CatergorieModel> categories = [/* 分类数据 */];
  CatergorieModel? catergorieModel;

  Future<void> _loadSavedCategory() async {
    String? savedCategoryId = await CasheHelper.getData('news');
    if (savedCategoryId != null) {
      catergorieModel = categories.firstWhere((cat) => cat.id == savedCategoryId);
      getSources(savedCategoryId);
      emit(NewsView());
    }
  }

  // 现有getSources、getNewsData等方法...
}

3. 修复onClick方法的逻辑

更新onClick,先赋值状态再保存缓存:

void onClick(CatergorieModel catergorieModel) {
  this.catergorieModel = catergorieModel;
  CasheHelper.saveData('news', catergorieModel.id);
  getSources(catergorieModel.id);
  emit(NewsView());
}

4. 简化HomeScreen的判断逻辑

由于Cubit初始化时已读取缓存,HomeScreen无需直接判断SharedPreferences:

body: NewsCubit.get(context).catergorieModel == null
    ? // 分类选择界面
    : const NewsScreen(),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:15:35