使用 Cubit Bloc 从另一个小部件更新小部件
Update a widget from another one with Cubit Bloc
我在屏幕上有两个小部件,一个加载小部件和一个按钮小部件我想在每次点击按钮时更改加载小部件的状态。
正在加载小部件
class LoadingWidget extends StatelessWidget {
const LoadingWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<LoadingCubit, bool>(
bloc: BlocProvider.of<LoadingCubit>(context),
builder: (context, loadingState) {
return Center(
child: Visibility(
visible: BlocProvider.of<LoadingCubit>(context).state,
child: const CircularProgressIndicator(
backgroundColor: Color(0xFF2C2C2C),
)),
);
});
}
}
加载肘
class LoadingCubit extends Cubit<bool> {
LoadingCubit() : super(true);
toggleLoading() {
emit(!state);
}
}
加载按钮
class AutoLoginButton extends StatelessWidget {
const AutoLoginButton({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<AutoLoginCubit, bool>(
bloc: BlocProvider.of<AutoLoginCubit>(context),
builder: (context, autoLoginState) => InkWell(
child: Row(
children: [
Icon(
autoLoginState == false
? Icons.check_box_outline_blank
: Icons.check_box,
),
],
),
onTap: () {
BlocProvider.of<AutoLoginCubit>(context).toggleAutoLogin();
},
),
);
}
}
纽扣肘
class AutoLoginCubit extends Cubit<bool> {
AutoLoginCubit() : super(false){
initState().then((value) => emit(value));
}
void toggleAutoLogin() async {
if (state == false) {
emit(true);
} else {
emit(false);
}
AutoLoginService().setAutoLoginState(state: state);
}
Future<bool> initState() async{
return await AutoLoginService().getAutoLoginState();
}
}
页面
Row(
children:[
BlocProvider(
create: (context) => AutoLoginCubit(),
child: const AutoLoginButton(),
),
BlocProvider(
create: (BuildContext context) => LoadingCubit(),
child: const LoadingWidget()),
]
)
你应该使用 MultiBlocProvider.
解决方法是:
MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AutoLoginCubit() ),
BlocProvider(create: (context) => LoadingCubit() ),
],
child: Row(
children:[ AutoLoginButton(), LoadingWidget()]
)
)
说明:
Flutter 为其视觉元素形成了一个树状结构(类似于 HTML 中的 DOM)。
Cubit/Blocs 附加到此节点树中的元素。
并且对给定节点的所有子节点可用。
要使其可见,必须将 Cubit 移到层次结构的上层:
您需要使用 BlocProvider.of<LoadingCubit>(context).toggleLoading();
在 AutoLoginButton onTap 函数上切换加载以触发加载小部件的重建,但为了能够在 LoadingCubit
上调用 toggleLoading()
您需要提供它在你的 AutoLoginButton
之上。所以我的解决方案是:
MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AutoLoginCubit()),
BlocProvider(create: (BuildContext context) => LoadingCubit()),
],
child: Row(
children: [
const AutoLoginButton(),
const LoadingWidget(),
],
),
),
我在屏幕上有两个小部件,一个加载小部件和一个按钮小部件我想在每次点击按钮时更改加载小部件的状态。
正在加载小部件
class LoadingWidget extends StatelessWidget {
const LoadingWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<LoadingCubit, bool>(
bloc: BlocProvider.of<LoadingCubit>(context),
builder: (context, loadingState) {
return Center(
child: Visibility(
visible: BlocProvider.of<LoadingCubit>(context).state,
child: const CircularProgressIndicator(
backgroundColor: Color(0xFF2C2C2C),
)),
);
});
}
}
加载肘
class LoadingCubit extends Cubit<bool> {
LoadingCubit() : super(true);
toggleLoading() {
emit(!state);
}
}
加载按钮
class AutoLoginButton extends StatelessWidget {
const AutoLoginButton({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocBuilder<AutoLoginCubit, bool>(
bloc: BlocProvider.of<AutoLoginCubit>(context),
builder: (context, autoLoginState) => InkWell(
child: Row(
children: [
Icon(
autoLoginState == false
? Icons.check_box_outline_blank
: Icons.check_box,
),
],
),
onTap: () {
BlocProvider.of<AutoLoginCubit>(context).toggleAutoLogin();
},
),
);
}
}
纽扣肘
class AutoLoginCubit extends Cubit<bool> {
AutoLoginCubit() : super(false){
initState().then((value) => emit(value));
}
void toggleAutoLogin() async {
if (state == false) {
emit(true);
} else {
emit(false);
}
AutoLoginService().setAutoLoginState(state: state);
}
Future<bool> initState() async{
return await AutoLoginService().getAutoLoginState();
}
}
页面
Row(
children:[
BlocProvider(
create: (context) => AutoLoginCubit(),
child: const AutoLoginButton(),
),
BlocProvider(
create: (BuildContext context) => LoadingCubit(),
child: const LoadingWidget()),
]
)
你应该使用 MultiBlocProvider.
解决方法是:
MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AutoLoginCubit() ),
BlocProvider(create: (context) => LoadingCubit() ),
],
child: Row(
children:[ AutoLoginButton(), LoadingWidget()]
)
)
说明: Flutter 为其视觉元素形成了一个树状结构(类似于 HTML 中的 DOM)。 Cubit/Blocs 附加到此节点树中的元素。 并且对给定节点的所有子节点可用。
要使其可见,必须将 Cubit 移到层次结构的上层:
您需要使用 BlocProvider.of<LoadingCubit>(context).toggleLoading();
在 AutoLoginButton onTap 函数上切换加载以触发加载小部件的重建,但为了能够在 LoadingCubit
上调用 toggleLoading()
您需要提供它在你的 AutoLoginButton
之上。所以我的解决方案是:
MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AutoLoginCubit()),
BlocProvider(create: (BuildContext context) => LoadingCubit()),
],
child: Row(
children: [
const AutoLoginButton(),
const LoadingWidget(),
],
),
),