I want to call the string function, I use package_info_plus
to get the packageName when I run the app, just like this:
class SplashScreenController extends GetxController {
late String one = '';
late RxString two = ''.obs;
@override
void onInit() {
_initPackageInfo();
_setImage();
Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
super.onInit();
}
@override
void onClose() {}
Future<void> _initPackageInfo() async {
final info = await PackageInfo.fromPlatform();
one = info.packageName;
}
String _setImage() {
if (one == 'com.package.one') {
return two.value = Images.one;
} else if (one == 'com.package.two) {
return two.value = Images.two;
} else {
return two.value = Images.one;
}
}
}
And when I try to call RxString two
inside Image.asset()
@override
Widget build(BuildContext context) {
print(controller.two);
return Obx(() => Scaffold(
body: Container(
color: const Color.fromARGB(255, 255, 255, 255),
alignment: AlignmentDirectional.center,
child: controller.one.isNotEmpty
? Image.asset(controller.two.toString())
: const SizedBox.shrink(),
)));
}
It show the null value, is there any way for me to use the packageName value in conditional case and then calling it in Image.asset()
widget?
CodePudding user response:
I have rewrite your controller and UI Code. Please check it out.
Controller (SplashScreen)
class SplashScreenController extends GetxController {
late RxString one = ''.obs;
late RxString two = ''.obs;
@override
void onInit() async {
await _initPackageInfo();
Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
super.onInit();
}
@override
void onClose() {}
Future<void> _initPackageSetImage() async {
final info = await PackageInfo.fromPlatform();
one.value = info.packageName;
switch(one.value){
case 'com.package.one':
two.value = Images.one;
break;
case 'com.package.two':
two.value = Images.two;
break;
default:
two.value = Images.one;
break;
}
}
}
UI (SplashScreen)
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: const Color.fromARGB(255, 255, 255, 255),
alignment: AlignmentDirectional.center,
child: Obx((){
print(controller.two.value);
if(controller.one.value.isNotEmpty){
return Image.asset(controller.two.value);
}
return const SizedBox.shrink();
}),
));
}
CodePudding user response:
This is not related really to Getx
, it's related to the Dart language programming and futures, here in this piece of code:
@override
void onInit() {
_initPackageInfo();
_setImage();
Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
super.onInit();
}
_initPackageInfo()
is an asynchronous method, which needs time to resolve (so the info
variable gets an PackageInfo
instance ), this means that executing it synchronously will still get you the instance, but it will not wait for it, and it will run _setImage()
immediately which at this point PackageInfo.fromPlatform()
did not get resolved yet, so it's null
, what you need to do is to make it wait until in have the instance then continues running other code :
@override
void onInit() {
_initPackageInfo().then((val) {
// this will be executed when _initPackageInfo() finishes.
_setImage();
Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
});
super.onInit();
}