You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:27:25