英文:
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);
  }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论