getx obx 不更新头像图片 - Flutter GetX

getx obx not updating avatar image - Flutter GetX

我想要实现的是在选择图片时更改CircleAvatar中的图片,代码如下:

ProfileController:

class ProfileController extends GetxController {
  final TextEditingController emailController = TextEditingController();
  final ImagePicker _picker = ImagePicker();
  Rx<String?> avatarPath = null.obs;


  avatarFromCamera() async {
    var localAvatar = await _picker.pickImage(
        source: ImageSource.camera, imageQuality: 50
    );

    if (localAvatar != null) {
      avatarPath = localAvatar.path.obs;
      update();
    }
  }

  avatarFromGallery() async {
    var localAvatar = await  _picker.pickImage(
        source: ImageSource.gallery, imageQuality: 50
    );

    if (localAvatar != null) {
      avatarPath = localAvatar.path.obs;
      update();
    }
  }

 String? emailValidator(String? value) {
    if (value == null || value.isEmpty) {
      return null;
    }

    if (!EmailValidator.validate(value, false)) {
      return 'Invalid email address';
    }
  }

  @override
  void onClose() {
    emailController.dispose();
    super.onClose();
  }

  String? emailValidator(String? value) {
    if (value == null || value.isEmpty) {
      return null;
    }

    if (!EmailValidator.validate(value, false)) {
      return 'Invalid email address';
    }
  }

 void save(GlobalKey<FormState> profileFormKey) {
    if (profileFormKey.currentState!.validate()) {
      print('valid');
    }
  }
}

这里是 ProfileScreen 小部件:

lass ProfileScreen extends StatelessWidget {
  final ProfileController _profileController = Get.put<ProfileController>(ProfileController());
  GlobalKey<FormState> profileFormKey = GlobalKey<FormState>();

  ProfileScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Update user details'),
      ),
      body: SingleChildScrollView(
        child: Form(
          key: profileFormKey,
          child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(30.0),
              child: TextFormField(
                keyboardType: TextInputType.text,
                controller: _profileController.emailController,
                decoration: const InputDecoration(
                  labelText: 'Enter email',
                ),
                validator: _profileController.emailValidator,
              ),
            ),
            Center(
              child: GestureDetector(
                onTap: () {
                  showModalBottomSheet(
                      context: context,
                      builder: (BuildContext bc) {
                        return SafeArea(
                          child: Wrap(
                            children: <Widget>[
                               ListTile(
                                  leading: const Icon(Icons.photo_library),
                                  title: const Text('Photo Library'),
                                  onTap: () {
                                    _profileController.avatarFromGallery();
                                    Navigator.of(context).pop();
                                  }),
                               ListTile(
                                leading: const Icon(Icons.photo_camera),
                                title: const Text('Camera'),
                                onTap: () {
                                  _profileController.avatarFromCamera();
                                  Navigator.of(context).pop();
                                },
                              ),
                            ],
                          ),
                        );
                      }
                  );
                },
                child:  CircleAvatar(
                  radius: 55,
                  backgroundColor: Colors.pink,
                  child: Obx(() =>(_profileController.avatarPath.value != null)
                      ? ClipRRect(
                    borderRadius: BorderRadius.circular(50),
                    child: Image.file(
                      File(_profileController.avatarPath.value!),
                      width: 100,
                      height: 100,
                      fit: BoxFit.fitHeight
                    ),
                  )
                      : Container(
                    decoration: BoxDecoration(
                        color: Colors.grey[200],
                        borderRadius: BorderRadius.circular(50)),
                    width: 100,
                    height: 100,
                    child: Icon(
                      Icons.camera_alt,
                      color: Colors.grey[800],
                    ),
                  ),
                ),
              ),
            )),
            Container(
              margin: const EdgeInsets.all(10),
              width: double.infinity,
              child: MaterialButton(
                color: Colors.blue,
                onPressed: () => _profileController.save(profileFormKey),
                child: const Text(
                  'Submit',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
          ],
        ),
        ),
      ),
    );
  }
}

如您所见,我有 Obx 和我的 avatarPath 反应式,我在任何地方都 运行 update 改变它,但它没有更新。我还尝试像这样 Rx<String> avatarPath = ''.obs; 使用空字符串作为 imagePath 的初始值,但它不起作用。我做错了什么???谢谢指教!!!

有两处需要修改。首先,将 avatarPath = localAvatar.path.obs; 更改为 avatarPath.value = localAvatar.path;。因为 localAvatar.path.obs 创建新的可观察对象并且更改不会反映到以前的观察者。

其次,创建一个新的无状态小部件,其底部 sheet 的构建器的小部件树类似于

showModalBottomSheet(
  context: context,
  builder: (BuildContext bc) {
        return CustomBottomView();
  }
);

然后在 CustomBottomView 中复制底部 sheet 小部件树。

class CustomBottomView extends GetView<ProfileController> {
  return YourBottomSheetWidgetTreeHere();
}

这里不用担心ProfileController。您已经在之前的路线中将其放入 DI。还是遇到问题先按照第一步走,第二步肯定能解决。