Flutter GetX状态管理不起作用



我面临的问题是ui文本没有得到更新。我想要的数据,在本例中是placeName,在DEBUG控制台上成功打印,但它不会改变文本小部件UI。我认为在Getx中的简单语句管理中,它会在方法中使用update((更新变量。我以前也遇到过类似的情况,但我无法解决,所以我不得不使用statefuleWidget来解决它。但是,这次我想用Getx继续这样做。

在此处输入图像描述

有人能帮我吗?

2021-11-10我更新了我的代码,但它仍然不起作用

2021-11-18我发现了改变函数返回类型(searchCoordinateAddress(的方法,并将其分配给我想要更新的变量(pickUpLocation(。

// home_controller.dart
class HomeController extends GetxController {
...
Rx<Address> pickUpLocation = Address().obs;
RxBool isLoading = false.obs;
...

void locatePosition() async {
...
...
//  String? address = await UberRepository.to.searchCoordinateAddress(position); // previous
// current
Address? address = await UberRepository.to.searchCoordinateAddress(position);
pickUpLocation(address);
isLoading(true);
}

// previous
/*
void updatePickUpLocationAddress(Address pickUpAddress) {
print("pickUpAddress.placeName: ${pickUpAddress.placeName}");
pickUpLocation(pickUpAddress);
print("pickUpLocation.value.placeName: ${pickUpLocation.value.placeName}");
}
}
*/
// uber_repository.dart
class UberRepository extends GetConnect {
static UberRepository get to => Get.find();
@override
void onInit() {
httpClient.baseUrl = 'https://maps.googleapis.com/';
super.onInit();
}
// Future<String?> // previous
// current
Future<Address?> searchCoordinateAddress(Position position) async {
String placeAddress = "";
String url =
'maps/api/geocode/json?latlng=${position.latitude},${position.longitude}&key=$mapKey';
final response = await get(url);
if (response.status.hasError) {
Future.error(response.statusText!);
} else {
placeAddress = response.body["results"][0]["formatted_address"];
Address userPickUpAddress = Address();
userPickUpAddress.latitude = position.latitude;
userPickUpAddress.longitude = position.longitude;
userPickUpAddress.placeName = placeAddress;

return userPickUpAddress; // current
// HomeController().updatePickUpLocationAddress(userPickUpAddress); // previous

}
// return placeAddress; // previous
}
}
// home.dart
class Home extends GetView<HomeController> {
const Home({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
...
body:  Stack(
children: [
GoogleMap(
padding: EdgeInsets.only(
bottom: controller.bottomPaddingOfMap.value,
),
mapType: MapType.normal,
myLocationButtonEnabled: true,
initialCameraPosition: controller.kGooglePlex,
myLocationEnabled: true,
zoomGesturesEnabled: true,
zoomControlsEnabled: true,
onMapCreated: (GoogleMapController googleMapController) {
controller.controllerGoogleMap.complete(googleMapController);
controller.newGoogleMapController = googleMapController;
// when map created and map is set correctly, call current location
controller.setBottomPaddingOfMap();
controller.locatePosition(); 
},
),
...
...
Expanded(
child: Obx(() => 
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TODO: UI update...
!controller.isLoading.value
? CircularProgressIndicator()
: Text(
controller.pickUpLocation.value != null
? controller.pickUpLocation.value.placeName!
: "Add Home",
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: false,
),
SizedBox(height: 4.0),
Text(
"Your living home address",
style: TextStyle(
color: Colors.black54,
fontSize: 12.0,
),
),
],
),
),
),
...
// address.dart
class Address {
String? placeFormattedAddress;
String? placeName;
String? placeId;
double? latitude;
double? longitude;
Address({
this.placeFormattedAddress,
this.placeName,
this.placeId,
this.latitude,
this.longitude,
});
}

您可以使用Obx来完成此操作。在控制器类中执行类似的操作

class HomeController extends GetxController {
Address get pickupLocation => _pickupLocation.value;
set pickupLocation(Address value) {
_pickupLocation.value = value;
}
Rx<Address> pickUpLocation= Rx<Address>(Address());
...
...
...

void updatePickUpLocationAddress(Address? pickUpAddress) {
pickUpLocation = pickUpAddress;
print("Here? ${pickUpLocation!.placeName!}"); // printed correctly as I intended
}
}

现在在你的UI类中使用Obx而不是像这个一样使用GetBuilder

// home.dart
class Home extends GetView<HomeController> {
const Home({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
...
...
...
...
Obx(() => controller.pickupLocation.placeName != null
? Text(controller.pickupLocation.placeName)
: Text('Add home')),
...

我认为您必须在小部件中调用pickUpLocation.refresh()。以下是getxdev页面中一个示例的相关部分https://pub.dev/packages/get:

// `Rx` don't have any clue when you change something inside user.
// So, for custom classes, we need to manually "notify" the change.
user.refresh();

最新更新