如何让SongDetailsBottomsheetController释放并在每次打开BottomSheet时重新初始化
class SongDetailsBottomsheet extends StatelessWidget {
final SongDetailsBottomsheetController controller;
SongDetailsBottomsheet({super.key, required MediaItem track})
: controller = Get.put(SongDetailsBottomsheetController(track: track));
@override
Widget build(BuildContext context) {
return const SizedBox(
height: 220,
child: Column(
children: [
SizedBox(width: 100,height: 100,)
],
),
);
}
}
class SongDetailsBottomsheetController extends GetxController {
// bool isLoading = true;
// late String avatarUrl;
final MediaItem track;
SongDetailsBottomsheetController({required this.track});
@override
void onInit() {
super.onInit();
debugPrint('start');
}
@override
void onReady() {
super.onReady();
debugPrint('ready');
// getArtistAvatar();
}
@override
onClose(){
super.onClose();
debugPrint('closing');
}
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return SongDetailsBottomsheet(track: track);
});
}
当按下按钮时,弹出BottomSheet,但关闭时不会打印"closing",当再次打开时,也不会重新调用OnInit()和OnReady(),每次传入的MediaItem都不同,但SongDetailsBottomsheetController中的MediaItem不变
调试信息:
I/flutter (25437): start
I/flutter (25437): ready
W/WindowOnBackDispatcher(25437): OnBackInvokedCallback is not enabled for the application.
W/WindowOnBackDispatcher(25437): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
W/WindowOnBackDispatcher(25437): OnBackInvokedCallback is not enabled for the application.
W/WindowOnBackDispatcher(25437): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
W/WindowOnBackDispatcher(25437): OnBackInvokedCallback is not enabled for the application.
W/WindowOnBackDispatcher(25437): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
D/SystemUtils(25437): [isSystemApp] begin android.app.Application@da53904
D/ScreenUtils(25437): isMultiWindow:0,userId:0
D/ScreenUtils(25437): hasVivoFreeformTasks:0,userId:0
D/ScreenUtils(25437): isLittleVExist:0,userId:0
D/SystemUtils(25437): userId:0
尝试使用Get.bottomsheet(),但问题依然存在
在 GetX 框架中,当你使用 Get.put()
来创建并存储一个控制器时,这个控制器实例会被存储在 GetX 的依赖注入容器中,直到它被显式地从容器中移除或应用程序的生命周期结束。这就是为什么你在多次打开和关闭 BottomSheet 时,SongDetailsBottomsheetController
的 onInit()
和 onReady()
方法没有被重新调用,并且 onClose()
方法也没有被调用的原因:因为同一个控制器实例被复用了。
要解决这个问题,你可以在每次需要显示 BottomSheet 时创建一个新的 SongDetailsBottomsheetController
实例,而不是从依赖注入容器中获取它。这里有一种方法来实现这一点:
Get.put()
的使用:在你的 SongDetailsBottomsheet
构造函数中,不要使用 Get.put()
来创建控制器实例。SongDetailsBottomsheet
类的成员变量(但不存储在 GetX 的依赖注入容器中)。showModalBottomSheet
不直接支持关闭回调,你可能需要在 BottomSheet 内部添加一个按钮或逻辑来触发控制器的清理或重新初始化。下面是一个修改后的示例,展示了如何在每次打开 BottomSheet 时创建一个新的控制器实例:
class SongDetailsBottomsheet extends StatelessWidget {
final MediaItem track;
late final SongDetailsBottomsheetController controller;
SongDetailsBottomsheet({super.key, required this.track}) {
// 在构造函数中直接创建控制器实例
controller = SongDetailsBottomsheetController(track: track);
// 你可以在这里监听控制器的 onClose 或其他生命周期事件
// 但请注意,BottomSheet 没有直接的方法来检测关闭事件
// 除非你添加了一个按钮或逻辑来手动触发它
}
@override
Widget build(BuildContext context) {
// 使用 controller 来进行 UI 更新或逻辑处理
return SizedBox(
height: 220,
child: Column(
children: [
// 你的 UI 组件
Text('Track Title: ${controller.track.title}'), // 假设 MediaItem 有一个 title 属性
],
),
);
}
@override
void dispose() {
// 当 Widget 被销毁时,你可以选择在这里释放控制器资源
// 但在这个案例中,由于每次打开都会创建一个新的实例,所以可能不需要
// 除非你在控制器中分配了需要手动释放的资源
super.dispose();
}
}
class SongDetailsBottomsheetController {
final MediaItem track;
SongDetailsBottomsheetController({required this.track});
// 你可以在这里添加你的初始化逻辑
void init() {
// 初始化代码
debugPrint('Initialized with track: ${track.title}'); // 假设 MediaItem 有一个 title 属性
}
// 你可以在这里添加其他需要的方法
}
// 显示 BottomSheet 的代码保持不变,但每次都会创建一个新的 SongDetailsBottomsheet 实例
请注意,由于 showModalBottomSheet
不提供直接的关闭回调,因此你可能需要在 BottomSheet 内部添加逻辑来触发控制器的某些清理操作。如果你确实需要检测 BottomSheet 的关闭事件,你可以考虑在 BottomSheet 内部添加一个按钮或使用其他 UI 组件来允许用户关闭它,并在该操作触发时执行必要的清理。
另外,请注意,我在上面的示例中移除了对 GetX 依赖注入的使用,因为在这个特定的情况下,每次都需要一个新的控制器实例。如果你仍然想使用 GetX 的功能,你可能需要寻找其他方式来管理控制器的生命周期,而不是简单地使用 Get.put()
。
我有一个关于android camerax架构的问题。我使用的是预览视图,效果非常好。问题与片段之间的事务有关。片段1具有previewView。当我切换到fragment2并返回fragment1时,我会再次绑定previewview,使它首先出现黑屏,然后预览显示在屏幕上。我不想看到黑屏。这个问题有什么解决办法吗?
下面的代码片段: 我尝试使用“automatickeepaliveClientMixin和@override bool get wantKeepAlive=>true”-即保持它活动,以便下次调用它时,它不会再次调用initState(),但是它没有工作。
问题内容: 当我运行以下代码时,两个测试用例都变为现实: 预期的行为 test1-成功 test2-失败(按预期该计数将变为3) 实际行为 test1-成功 test2-成功 为什么junit 与每个测试方法都调用。它是junit中的错误或有意提供。 问题答案: 每种测试方法的新实例 对于每种测试方法,将创建Junit的行为的 新实例。 因此,在您的情况下,这两种方法的变量都将具有value ,因
每当从我的要素文件开始执行新方案时,就会启动一个新浏览器。我希望浏览器只在我的第一个场景执行时启动一次,在场景的其余部分,不应打开新的浏览器。 我已经把我的浏览器打开代码写进了类下的注释中。
当我在执行语句后检查分配给的内存地址时,我发现内存内容为0。因为我读到没有将内存初始化为0,所以这是正确的行为吗?
问题内容: 是否可以在运行时重新初始化Spring Bean? 我的Bean使用静态设置,在某些情况下会更改,然后我必须重新初始化Bean。 问题答案: 你可以通过三种方法在spring上下文中更新单例bean,可以选择一种适合你的用例: 在Bean中重新加载方法在Bean中 创建一个方法,该方法将更新/重新加载其属性。根据你的触发器,从spring上下文访问bean,然后调用reload方法更新