英文:
Build method not called when Rx<File?> modified
问题
以下是翻译好的部分:
Controller
class TestPageController extends GetxController {
// 成员
late Rx<File?> avatarImage = null.obs;
// 方法:设置初始页面数据
Future<void> initPage() async {
avatarImage = Rx<File?>(File(defaultAvatarPath));
}
// 方法:选择头像图片
Future<void> pickAvatarImage() async {
final XFile? pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery);
avatarImage = Rx<File?>(File(pickedImage!.path));
}
// Getx 控制器的生命周期
@override
void onInit() async {
super.onInit();
await initPage();
}
}
Page
class TestPage extends StatelessWidget {
TestPage({Key? key}) : super(key: key);
final controller = Get.put(TestPageController());
@override
Widget build(BuildContext context) {
return Obx(
() {
return CupertinoPageScaffold(
child: Column(
children: [
Stack(
children: [
CircleAvatar(
radius: 64,
backgroundImage: Image.asset(controller.avatarImage.value!.path).image,
backgroundColor: Colors.black,
),
Positioned(
bottom: -10,
left: 85,
child: AdaptiveIconButton(
buttonHandler: (p0) => {
controller.pickAvatarImage(),
},
buttonIcon: const Icon(
Icons.add_a_photo,
color: Colors.white,
),
),
),
],
),
],
),
);
},
);
}
}
英文:
When the Rx<File?> is updated in the controller the build method is not called in the corresponding page. My code is below and this DOES work if I use GetBuilder and call update(), but I want to understand why the implementation below does not work when it does in every other situation I use it? The expected behavior is that the backgroundImage of the CircleAvatar would update with the newly selected image.
Controller
class TestPageController extends GetxController {
// members
late Rx<File?> avatarImage = null.obs;
// Method: set inital page data
Future<void> initPage() async {
avatarImage = Rx<File?>(File(defaultAvatarPath));
}
// Method: pick image for avatar
Future<void> pickAvatarImage() async {
final XFile? pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery);
avatarImage = Rx<File?>(File(pickedImage!.path));
}
//** Lifecycle of Getx Controller **//
@override
void onInit() async {
super.onInit();
await initPage();
}
}
Page
class TestPage extends StatelessWidget {
TestPage({Key? key}) : super(key: key);
final controller = Get.put(TestPageController());
@override
Widget build(BuildContext context) {
return Obx(
() {
return CupertinoPageScaffold(
child: Column(
children: [
Stack(
children: [
CircleAvatar(
radius: 64,
backgroundImage: Image.asset(controller.avatarImage.value!.path).image,
backgroundColor: Colors.black,
),
Positioned(
bottom: -10,
left: 85,
child: AdaptiveIconButton(
buttonHandler: (p0) => {
controller.pickAvatarImage(),
},
buttonIcon: const Icon(
Icons.add_a_photo,
color: Colors.white,
),
),
),
],
),
],
),
);
},
);
}
}
答案1
得分: 1
你可以使用 Rxn
。Getx 用于可空值。你需要修改你的 GetxController,如下所示。
class TestPageController extends GetxController {
// 成员
final avatarImage = Rxn<File>();
// Getx 控制器的生命周期
@override
void onInit() async {
super.onInit();
avatarImage.value = File(defaultAvatarPath);
}
// 方法:选择头像图片
Future<void> pickAvatarImage() async {
final XFile? pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery);
avatarImage.value = File(pickedImage!.path);
}
}
英文:
You can user Rxn
. Getx has for nullable value. You need to modified your GetxController like.
class TestPageController extends GetxController {
// members
final avatarImage = Rxn<File>();
//** Lifecycle of Getx Controller **//
@override
void onInit() async {
super.onInit();
avatarImage.value = File(defaultAvatarPath);
}
// Method: pick image for avatar
Future<void> pickAvatarImage() async {
final XFile? pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery);
avatarImage.value = File(pickedImage!.path);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论