Flutter组件封装:页面点击事件拦截

一、需求来源

用户在(游客模式)浏览某个界面(需要某种权限)时,以登录权限举例。

此时未登录状态下:正确跳转对应的页面,完成相应逻辑。我们需要用户在点击页面任意位置时,统一唤起登录页面。

未登录状态下:正确跳转对应的页面,完成相应逻辑。

开始想通过监听实现,但是无法实现,经过苦苦思索,突然某一天就灵光一闪解决了,封装了一个小组件 TapGestureIntercept。

当 TapGestureIntercept 组件的 ignoring 为 true 时,其包裹范围内的所有点击事件不响应,它 的 onTap 会代替所有子组件的响应事件;ignoring 为 false 时,子组件点击事件正常,它 的 onTap 不会调用。

二、使用示例

less 复制代码
class ClickNotificationDemo extends StatelessWidget {
  const ClickNotificationDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("页面点击拦截")),
      body: TapGestureIntercept(
        ignoring: true,
        onTap: () {
          DLog.d('页面点击事件');
        },
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
          // decoration: BoxDecoration(color: Colors.green),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              ElevatedButton(
                onPressed: () {
                  debugPrint("按钮1");
                },
                child: Text("按钮1"),
              ),
              ElevatedButton(
                onPressed: () {
                  debugPrint("按钮2");
                },
                child: Text("按钮2"),
              ),
              GestureDetector(
                onTap: () {
                  debugPrint("点击黄色区域");
                },
                child: Container(
                  color: Colors.yellow,
                  padding: EdgeInsets.all(20),
                  child: Text("点击黄色区域"),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

三、源码

scala 复制代码
//
//  TapGestureIntercept.dart
//  flutter_templet_project
//
//  Created by shang on 2025/9/12 21:36.
//  Copyright © 2025/9/12 shang. All rights reserved.
//

import 'package:flutter/widgets.dart';

/// 拦截被包裹部分的事件响应
class TapGestureIntercept extends StatelessWidget {
  const TapGestureIntercept({
    super.key,
    this.behavior = HitTestBehavior.opaque,
    this.ignoring = true,
    required this.onTap,
    required this.child,
  });

  final HitTestBehavior? behavior;

  /// Defaults to true.
  final bool ignoring;

  final VoidCallback onTap;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: behavior,
      onTap: ignoring ? onTap : null,
      child: IgnorePointer(
        ignoring: ignoring,
        child: child,
      ),
    );
  }
}

最后、总结

本诉那会死一个实战小技巧,没有这个组件,遇到类登录权限类页面就很难受,难道要我在页面20+的点击方法里做同样的拦截(判断是否已登录)?

github

相关推荐
宇余1 小时前
Unibest:新一代uni-app工程化最佳实践指南
前端·vue.js
性野喜悲1 小时前
ts+uniapp小程序时间日期选择框(分开选择)
前端·javascript·vue.js
woshijunjunstudy1 小时前
Flutter .obx 与 Rxn<T>的区别
flutter·getx
P***25393 小时前
前端构建工具缓存清理,npm cache与yarn cache
前端·缓存·npm
好奇的菜鸟3 小时前
解决 npm 依赖版本冲突:从 “unable to resolve dependency tree“ 到依赖管理高手
前端·npm·node.js
lcc1873 小时前
Vue 内置指令
前端·vue.js
lijun_xiao20093 小时前
前端React18入门到实战
前端
o***Z4483 小时前
前端响应式设计资源,框架+模板
前端
IT_陈寒4 小时前
Vue 3.4 正式发布:5个不可错过的性能优化与Composition API新特性
前端·人工智能·后端
N***73854 小时前
前端无障碍开发资源,WCAG指南与工具
前端