Flutter Flatter bloc以及bloc状态更改如何在使用这两者更新小部件/UI之前触发第二次异步调用?(附代码)
如何加载一组本地图像以在小部件中显示(注意这是异步的-请参见下面的函数),该小部件由“设置”的颤振块的状态变化触发(基于该变化)?注意,这个团也通过水合团持续存在。因此,我要问的用例是如何在flatter(注意我使用的是flatter_bloc)中对其进行编码: 用例-在同一个小部件上呈现不同的图像集,根据用户去的“房间”动态显示2D点击冒险类型游戏的房间。房间变更事件被传递给SettingsBloc,然后该SettingsBloc将确定要移动到的新“房间”。这个新的“房间”状态是通过Bloc概念提供的,但是我如何&在哪里异步加载这个房间所需的特定图像集(编译时没有设置)?(使用我拥有的CustomPainter(即绘制到画布上的图像)将其提供给dynamic room rendering小部件) 例如,建议采用哪种方法进行此操作?(理想情况下,实现这一点的代码是什么样子的) a) 监听小部件中“房间”的变化,然后触发(在小部件中)调用异步函数来动态加载ui?但如果是,您如何在小部件中的代码中实现这一点?(或者这不是最佳实践)。请参阅下面我的代码,它确实工作/运行,但似乎有一个无限循环正在发生或正在运行 b) 我是否应将图像设置为单独的组(例如图像组)。但在这种情况下,需要什么样的颤振代码来实现这一点:即Flutter Flatter bloc以及bloc状态更改如何在使用这两者更新小部件/UI之前触发第二次异步调用?(附代码),flutter,dart,flutter-bloc,dart-async,Flutter,Dart,Flutter Bloc,Dart Async,如何加载一组本地图像以在小部件中显示(注意这是异步的-请参见下面的函数),该小部件由“设置”的颤振块的状态变化触发(基于该变化)?注意,这个团也通过水合团持续存在。因此,我要问的用例是如何在flatter(注意我使用的是flatter_bloc)中对其进行编码: 用例-在同一个小部件上呈现不同的图像集,根据用户去的“房间”动态显示2D点击冒险类型游戏的房间。房间变更事件被传递给SettingsBloc,然后该SettingsBloc将确定要移动到的新“房间”。这个新的“房间”状态是通过Bloc概
- 用户在UI中执行某些操作来触发事件并将其传递给SettingsBloc
- 然后,设置SBLOC可确定“房间”因此发生变化,并改变/发出新的“currentRoom”
- 然后,setingsbloc将触发一个aynch请求,以便ImagesBlock(以某种方式)使用下面的异步代码获取此“房间”的新ui.Images列表
- 然后,UI/小部件需要获取“字符串室”和UI.Image的列表的更改
这是我迄今为止对上述方法(a)的最佳尝试。在UI重新更改背景中工作,但似乎存在无限循环: 日志记录:
Launching lib/main.dart on iPhone 12 Pro Max in debug mode...
lib/main.dart:1
Xcode build done. 29.5s
Connecting to VM Service at ws://127.0.0.1:49364/lyUIDblZgmY=/ws
flutter: game_main.build ----------------------------
flutter: trying to get room data for current room: room2
flutter: About to load imagename:plane.png
flutter: game_main.build ----------------------------
flutter: trying to get room data for current room: room2
flutter: About to load imagename:plane.png
flutter: game_main.build ----------------------------
flutter: trying to get room data for current room: room2
flutter: About to load imagename:plane.png
flutter: game_main.build ----------------------------
ETC ETC
代码:
导入'dart:async';
导入“dart:键入的_数据”;
将“dart:ui”导入为ui;
导入“包:冒险/ui/widgets/game_painter.dart”;
导入“包:flifter/services.dart”;
进口“包装:颤振团/颤振团.飞镖”;
导入“package:adventure/bloc/settings_cubit.dart”;
导入“套装:冒险/游戏设计/房间.飞镖”;
进口“包装:颤振/材料.省道”;
导入“package:touchable/touchable.dart”;
类GameMain扩展了StatefulWidget{
GameMain({Key}):super(Key:Key);
@凌驾
_GameMostate createState()=>\u GameMostate();
}
类\u GameMostate扩展状态{
final RoomsData RoomsData=RoomsData.getPopulated();
ui.Image\u背景图像;
Future\u loadImageAsync(imageString)异步{
ByteData bd=等待rootBundle.load(imageString);
最终Uint8List字节=Uint8List.view(bd.buffer);
final ui.Codec Codec=wait ui.instantialeimagecodec(字节);
final ui.Image Image=(wait codec.getNextFrame()).Image;
返回图像;
}
Future\u updateBackgroundImageState(字符串imagename)异步{
打印(‘即将加载imagename:$imagename’);
final image=await_loadImageAsync('assets/images/$imagename');
设置状态(){
_背景图像=图像;
});
}
@凌驾
小部件构建(构建上下文){
打印('game_main.build--------------------');
//获取持久数据设置
setingscubit setingscubit=context.watch();
//获取房间配置(对于我们现在所在的房间)
print('尝试获取当前文件室的文件室数据:${settingsCubit.state.currentRoom}');
Room roomData=roomsData.getRoom(设置scubit.state.currentRoom);
//更新背景图像
_updateBackgroundImageState(roomData.backgroundImage);
//创建并返回画布
返回容器(
孩子:BlocBuilder(
生成器:(上下文、状态){
返回堆栈(子级:[
CanvasTouchDetector(
生成器:(上下文)=>CustomPaint(
画师:游戏画师(上下文、设置位、房间数据、背景图像)
)
),
扁平按钮(
//用于测试对背景图像的更改
颜色:颜色,蓝色,
textColor:Colors.white,
已按下:(){
var newRoomString=settingsCubit.state.currentRoom=='room1'?'room2':'room1';
setingscubit.setRoom(newRoomString);
},
子:文本(
“扁平按钮”,
样式:TextStyle(fontSize:20.0),
),
),
]);
}
)
);
}
}
您的代码的问题是您将设置状态放在构建中,因此它称为build->\u updateBackgroundImage->setStatus->rebuild->\u updateBackgroundImage。。。(无限)
我认为日期更新流程如下所示:
change SettingsCubit -> get RoomData -> (wait for async image data) -> _updateBackgroundImage
问题是,如果图像仍在加载中,您希望显示什么?
答案可能是:
class SettingsCubit extends Cubit{
...
Future setRoom(String newRoom) async {
// emit state (imageIsLoading = true)
// load image async func
// emit state (imageIsLoading = false, image data update in state)
}
}
...
@override
Widget build(BuildContext context) {
SettingsCubit settingsCubit = context.watch<SettingsCubit>();
if(settingsCubit.state.imageIsLoading){
// show what do you want to show when image is not ready
}else{
// show room with image (ex. from settingsCubit.state.imageData)
}
类设置位扩展了Cubit{
...
未来设置室(字符串newRoom)异步{
//发射状态(imageIsLoading=true)
//加载图像异步函数
//发射状态(imageIsLoading=false,图像数据更新处于状态)
}
}
...
@凌驾
威奇
class SettingsCubit extends Cubit{
...
Future setRoom(String newRoom) async {
// emit state (imageIsLoading = true)
// load image async func
// emit state (imageIsLoading = false, image data update in state)
}
}
...
@override
Widget build(BuildContext context) {
SettingsCubit settingsCubit = context.watch<SettingsCubit>();
if(settingsCubit.state.imageIsLoading){
// show what do you want to show when image is not ready
}else{
// show room with image (ex. from settingsCubit.state.imageData)
}