Flutter Release版本GetX UI未完全构建问题求助
Flutter Release版本UI构建异常问题
首次安装启动应用时一切正常,但退出后重新打开,UI会出现构建异常。
- 预期效果:登录界面布局正常,所有元素排版整齐、位置正确
- 异常效果:登录界面元素错乱,布局偏移,显示异常
观察关键点
- 问题与GetX及Get控制器强相关:引入GetX前无此问题,近期用GetX构建的其他应用也出现类似错误
- 现象反复:间隔一段时间重新打开应用恢复正常,退出后再次打开又异常
- 技术架构:采用GetX框架,已将视图、控制器和绑定分离
相关代码
main.dart
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:sizer/sizer.dart'; import 'package:travel_mate/app/utils/my_translations.dart'; import 'package:travel_mate/app/utils/themes.dart'; import 'app/modules/Bindings/login_binding.dart'; import 'app/routes/app_pages.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await GetStorage().initStorage; runApp( Sizer( builder: (BuildContext context, Orientation orientation, DeviceType deviceType) { var isDark = GetStorage().read('isDark'); return GetMaterialApp( defaultTransition: Transition.cupertino, translations: MyTranslations(), locale: Locale('en'), fallbackLocale: Locale('np'), themeMode: isDark != null ? isDark ? ThemeMode.dark : ThemeMode.light : ThemeMode.system, debugShowCheckedModeBanner: false, title: "Application", getPages: AppPages.routes, initialRoute: GetStorage().read('token') != null ? AppPages.INITIAL : AppPages.SECONDARY, theme: lightTheme, darkTheme: darkTheme, initialBinding: LoginBinding(), ); }, ), ); }
login_binding.dart
import 'package:get/get.dart'; import 'package:travel_mate/app/modules/Controller/auth_controller.dart'; import 'package:travel_mate/app/modules/Controller/login_controller.dart'; class LoginBinding extends Bindings { @override void dependencies() { Get.put(LoginController()); Get.put(AuthController()); } }
login_controller.dart
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:travel_mate/app/models/user.dart'; import 'package:travel_mate/app/modules/Controller/auth_controller.dart'; import 'package:travel_mate/app/modules/views/tab/tab_view.dart'; class LoginController extends GetxController { GlobalKey<FormState> formKey = GlobalKey(); TextEditingController emailOrUsernameController = TextEditingController(); TextEditingController passwordController = TextEditingController(); var isLoading = false.obs; Rx<User?>? user; @override void dispose() { super.dispose(); emailOrUsernameController.dispose(); passwordController.dispose(); } final count = 0.obs; void increment() => count.value++; void login() async { if (formKey.currentState!.validate()) { isLoading.value = true; Rx<User?> response = (await AuthController.instance .login(emailOrUsernameController.text, passwordController.text)) .obs; if (response.value != null) { GetStorage().write('token', response.value!.token); Get.offAndToNamed('/tab'); } isLoading.value = false; } } void clearFields() { emailOrUsernameController.clear(); passwordController.clear(); } String? validateEmailOrUsername(String? value) { { if (value!.isEmpty) { return "Email or username can't be empty!"; } else if (!GetUtils.isEmail(value)) { return "Not a valid email address!"; } return null; } } String? validatePassword(String? value) { { if (value!.isEmpty) { return "Password can't be empty!"; } else if (value.length < 8) { return "Password can't be less than 8 characters!"; } return null; } } }
login_view.dart
import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:sizer/sizer.dart'; import 'package:travel_mate/app/global_components/my_text_field.dart'; import 'package:travel_mate/app/modules/views/components/custom_button.dart'; import 'package:travel_mate/app/utils/colors.dart'; import '../Controller/login_controller.dart'; class LoginView extends GetView<LoginController> { const LoginView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: SingleChildScrollView( keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, child: Column( children: [ Container( margin: EdgeInsets.symmetric(horizontal: 5.w, vertical: 5.w), //FORMS START FROM HERE child: Form( key: controller.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ //Main art and logo Center( child: SvgPicture.asset( 'assets/images/login_art.svg', width: 75.w, ), ), SizedBox( height: 1.h, ), Center( child: Text( 'TravelMate', style: TextStyle( fontFamily: 'Comic Sans Ms', fontSize: 22.5.sp, color: primaryColor, ), ), ), SizedBox( height: 2.h, ), Text( 'login'.tr, style: TextStyle( fontFamily: GoogleFonts.poppins(fontWeight: FontWeight.bold) .fontFamily, fontSize: 15.sp, color: primaryColor, ), ), SizedBox( height: 2.h, ), //Username Field MyTextField( textEditingController: controller.emailOrUsernameController, validator: controller.validateEmailOrUsername, textInputAction: TextInputAction.next, labelText: 'emailLabel'.tr, ), SizedBox( height: 3.h, ), //Password Field MyTextField( validator: controller.validatePassword, textEditingController: controller.passwordController, textInputAction: TextInputAction.done, labelText: 'passwordLabel'.tr, isPassword: true, ), SizedBox( height: 3.h, ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ InkWell( onTap: () {}, child: Text( 'forgot'.tr, style: TextStyle( fontFamily: GoogleFonts.poppins().fontFamily), ), ) ], ), SizedBox( height: 4.h, ), //Login button Obx( () => CustomButton( onTap: controller.login, isLoading: controller.isLoading.value, title: 'login'.tr), ), SizedBox( height: 4.h, ), //Sign in with google button SizedBox( height: 4.h, ), //Not registered yet button Center( child: Text.rich( TextSpan( style: TextStyle( fontFamily: GoogleFonts.poppins().fontFamily, fontSize: 12.sp, // color: const Color(0xff000000), ), children: [ TextSpan( text: 'registerText'.tr, ), TextSpan( recognizer: TapGestureRecognizer() ..onTap = (() { Get.toNamed('/sign-up'); }), text: 'signup'.tr, style: TextStyle( color: const Color(0xff0189e2), ), ), ], ), textHeightBehavior: TextHeightBehavior( applyHeightToFirstAscent: false), textAlign: TextAlign.center, softWrap: false, ), ), ], ), ), ), ], ), ), ), ); } }
内容的提问来源于stack exchange,提问作者Suraj
相关产品推荐
相关产品推荐

