我有一个 Flutter 应用程序,我想根据共享首选项中存储的值在两个屏幕之间切换。我正在使用 Cubit 包进行状态管理。目前,即使 SharedPreferences 中的值不同,应用程序始终显示
NewsScreen
,并将类别模型设置为“运动”。
这是我的代码的简化版本:
// HomeScreen
// ...
class HomeScreen extends StatelessWidget {
HomeScreen({super.key});
static const String routeName = 'homeScreen';
List<CatergorieModel> categories = [
CatergorieModel(
name: 'Sports',
image: 'assets/images/sports.png',
id: 'sports',
color: const Color(0xffC91C22),
),
// ... more of Categroies
];
@override
Widget build(BuildContext context) {
return BlocBuilder<NewsCubit, HomeState>(
builder: (context, state) {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
image: DecorationImage(
image: AssetImage('assets/images/pattern.png'),
fit: BoxFit.cover,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
actions: [
IconButton(
onPressed: () {
Navigator.pushNamed(context, SearchScreen.routeName);
},
icon: const Icon(Icons.search),
),
],
title: Text(
NewsCubit.get(context).catergorieModel == null
? 'News App'
: NewsCubit.get(context).catergorieModel?.name ??
'News App',
style:
GoogleFonts.exo(fontSize: 22, fontWeight: FontWeight.w600),
),
),
drawer: DarwerWidget(
makeModelNull: NewsCubit.get(context).makeModelNull,
),
body: NewsCubit.get(context).catergorieModel == null &&
CasheHelper.getData('news') == null
? Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Pick your Category \n of your intrest',
style: GoogleFonts.poppins(
fontSize: 25, fontWeight: FontWeight.w500),
),
const SizedBox(
height: 20,
),
Expanded(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: .79,
crossAxisSpacing: 18,
mainAxisSpacing: 18),
itemCount: categories.length,
itemBuilder: (context, index) {
return GridViewItemWidget(
OnClick: NewsCubit.get(context).onClick,
index: index,
catergorieModel: categories[index]);
},
),
),
],
),
)
: const NewsScreen(),
),
);
},
);
}
}
onClick(CatergorieModel catergorieModel) {
CasheHelper.saveData('news', this.catergorieModel!.id);
emit(NewsView());
}
}
// NewsScreen
class NewsScreen extends StatelessWidget {
static const String routeName = 'news_screen';
const NewsScreen({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>
NewsCubit()..getSources(NewsCubit.get(context).catergorieModel?.id ?? 'sports'),
child: BlocConsumer<NewsCubit, HomeState>(listener: (context, state) {
if (state is HomeLoadindState) {
const Center(child: CircularProgressIndicator());
} else if (state is HomeSorcesErrorState) {
const Center(
child: Text('No News'),
);
} else if (state is HomeSorcesSuccessState) {
NewsCubit.get(context).getNewsData();
}
}, builder: (context, state) {
var cubit = NewsCubit.get(context);
return Column(
children: [
const TabBarWidget(),
Expanded(
child: ListView.builder(
itemCount: cubit.articlesList.length,
itemBuilder: (context, index) {
return ArticlesNewsWidget(
articles: NewsCubit.get(context).articlesList[index],
);
},
),
)
// Expanded(
// child: ListView.builder(
// itemCount: cubit.articles.length,
// itemBuilder: (context, index) {
// return ArticlesNewsWidget(
// articles: NewsCubit.get(context).articles[index],
// );
// },
// ),
// )
],
);
}),
);
}
}
我希望
NewsScreen
显示基于 SharedPreferences 中存储的值的数据。但是,它始终显示“运动”类别。
我做错了什么?如何使
NewsScreen
根据 SharedPreferences 中保存的值显示正确的类别?任何见解或指导将不胜感激。
看起来像在
NewsScreen
中,您第二次创建了 NuewCubit
的新实例:
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>
NewsCubit()..getSources(NewsCubit.get(context).catergorieModel?.id ?? 'sports'),
...
所以,你在这里不需要
BlocProvider
,你已经在小部件树中创建了 NewCubit
,你只需要使用它,例如与 BlocConsumer
。
此外,您不需要共享首选项,因为您可以将选择的类别存储在肘状态中并从那里获取它。更多信息请参见 bloc 文档。