Flutter中GestureDetector的onTap触发栈溢出错误求助
Flutter GetX 登录点击触发栈溢出问题解决
问题重现
在controller.dart中定义SigninController控制器,在view.dart中调用其handleSignIn方法实现第三方登录时,点击登录按钮(GestureDetector)触发栈溢出错误。
相关代码
controller.dart
class SigninController extends GetxController { // SigninController(); final state = SigninController(); final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['openid']); Future<void> handleSignIn(String type) async { //number 1 = email, number 2 = google, number 3 = facebook, number 4 = apple, number 5 = phone try { if (type == "phone") { if (kDebugMode) { print("Logging in with phone"); } } else if (type == "google") { var user = await _googleSignIn.signIn(); if (user != null) { String? displayName = user.displayName; String email = user.email; String id = user.id; String photo = user.photoUrl ?? "assets/icons/google.png"; LoginRequestEntity loginPanelListRequestEntity = LoginRequestEntity(); loginPanelListRequestEntity.avatar = photo; loginPanelListRequestEntity.name = displayName; loginPanelListRequestEntity.avatar = photo; loginPanelListRequestEntity.open_id = id; loginPanelListRequestEntity.type = 2; } } else { if (kDebugMode) { print("Login type not defined"); } } } catch (e) { if (kDebugMode) { print("Login error $e"); } } } }
view.dart 登录按钮组件
Widget _buildThirdPartyLogin(String loginType, String logo) { return GestureDetector( onTap: () => controller.handleSignIn(loginType), child: Container( width: 295.w, height: 44.h, margin: EdgeInsets.only(bottom: 20.h), decoration: BoxDecoration( color: AppColors.primaryBackground, borderRadius: const BorderRadius.all(Radius.circular(5)), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), spreadRadius: 1, blurRadius: 2, offset: const Offset(0, 1)) ]), child: Row(children: [ Container( padding: EdgeInsets.only(left: 40.w, top: 5.w, bottom: 5.w), child: Image.asset("assets/icons/$logo.png"), ), Container( padding: EdgeInsets.only(left: 20.w), child: Text( "Sign up with $loginType", style: TextStyle( color: AppColors.primaryText, fontSize: 16.sp, fontWeight: FontWeight.bold), ), ) ]), ), ); }
报错信息
Handler: "onTap" Recognizer: TapGestureRecognizer#4f5fc debugOwner: GestureDetector state: possible won arena finalPosition: Offset(205.4, 249.4) finalLocalPosition: Offset(170.0, 21.2) button: 1 sent tap down
错误根源
栈溢出的核心原因是SigninController类内部定义了final state = SigninController();,这会导致无限递归实例化:
- 创建
SigninController实例时,会初始化state属性,而state又会创建新的SigninController实例 - 新实例同样会初始化自身的
state属性,再次创建新实例,循环往复直到栈内存耗尽
修复方案
删除final state = SigninController();这一行代码。如果需要管理控制器状态,应使用GetX标准的状态管理方式(比如单独定义状态类,而非直接实例化自身)。
修复后的controller.dart代码:
class SigninController extends GetxController { final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['openid']); Future<void> handleSignIn(String type) async { //number 1 = email, number 2 = google, number 3 = facebook, number 4 = apple, number 5 = phone try { if (type == "phone") { if (kDebugMode) { print("Logging in with phone"); } } else if (type == "google") { var user = await _googleSignIn.signIn(); if (user != null) { String? displayName = user.displayName; String email = user.email; String id = user.id; String photo = user.photoUrl ?? "assets/icons/google.png"; LoginRequestEntity loginPanelListRequestEntity = LoginRequestEntity(); loginPanelListRequestEntity.avatar = photo; loginPanelListRequestEntity.name = displayName; loginPanelListRequestEntity.open_id = id; loginPanelListRequestEntity.type = 2; } } else { if (kDebugMode) { print("Login type not defined"); } } } catch (e) { if (kDebugMode) { print("Login error $e"); } } } }
验证
修复后重新运行项目,点击第三方登录按钮,栈溢出错误将不再出现,handleSignIn方法可正常执行。
内容的提问来源于stack exchange,提问作者Xenomorphing79
相关产品推荐
相关产品推荐

