如何在Flutter中捕获并停止所有点击事件的传播。

huangapple go评论54阅读模式
英文:

How capture and stop propagation of all taps in flutter

问题

在我的应用中,我想要渲染整个应用,但如果用户未登录,当他们点击屏幕上的任何内容时,我希望弹出模态底部表单提示他们登录。

我希望能够用GestureDetector包裹整个屏幕,但似乎嵌套的按钮会优先接收到点击事件。

我希望能够使用Listener,然后在PointerUp时取消(停止传播/冒泡)事件,但这似乎不太可能。

我希望能够重叠一个透明Container,如果用户未登录,捕获所有的点击事件,但我不确定这是否可能。

在Flutter中有没有一种优雅的方法可以做到这一点,而不必在每个嵌套小部件的onTap处理程序中添加代码来检查用户是否已登录?

英文:

In my app, I want to render the whole app but if the user is not logged in then I want to pop up the modal bottom sheet to prompt them to log in if they tap on anything on the screen.

I was hoping to be able to wrap the whole screen with a GestureDetector but it seems that the nested buttons get the tap events first.

I was hoping I could use a Listener and then cancel (stop propagation/bubbling) the event on PointerUp but this doesn't appear to be possible.

I was hoping to be able to overlap a transparent Container to capture all taps if the user is not logged in but I am not sure if this is possible either.

Is there an elegant way to do this in Flutter without having to add code to check for logged-in user on each nested widget's onTap handler?

答案1

得分: 1

感谢 @pskink 提供的指引 - 这为我解决了问题:

class LoginHandlerWrapper extends StatelessWidget {
  final Widget child;
  final bool absorbPointer =
      FirebaseAuth.instance.currentUser?.isAnonymous == true;

  LoginHandlerWrapper({super.key, required this.child});

  @override
  Widget build(context) {
    return Listener(
        onPointerDown: (event) {
          if (FirebaseAuth.instance.currentUser?.isAnonymous == true) {
            showModalBottomSheet(
                context: context, builder: (context) => const SignIn());
          }
        },
        child: AbsorbPointer(
          absorbing: absorbPointer,
          child: child,
        ));
  }
}
英文:

Thank you for the pointer @pskink - this solved the problem for me:

class LoginHandlerWrapper extends StatelessWidget {
  final Widget child;
  final bool absorbPointer =
      FirebaseAuth.instance.currentUser?.isAnonymous == true;

  LoginHandlerWrapper({super.key, required this.child});

  @override
  Widget build(context) {
    return Listener(
        onPointerDown: (event) {
          if (FirebaseAuth.instance.currentUser?.isAnonymous == true) {
            showModalBottomSheet(
                context: context, builder: (context) => const SignIn());
          }
        },
        child: AbsorbPointer(
          absorbing: absorbPointer,
          child: child,
        ));
  }
}

huangapple
  • 本文由 发表于 2023年5月23日 00:03:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76308022.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定