Flutter触摸区域调整插件hit_slop的使用

Flutter触摸区域调整插件hit_slop的使用

Hit Slop

HitSlop 增加了小部件的点击范围,而不会影响树中其他小部件的布局。

HitSlop(
  slop: const EdgeInsets.all(8),
  onTap: () {
    print('hit box tapped');
  }
  child: const Icon(
    Icons.add,
    color: Colors.black,
    size: 24,
  ),
)

安装

flutter pub add hit_slop

使用

与使用 Padding 小部件等其他方法不同,HitSlop 不会改变周围小部件的布局,也不需要将您的小部件包裹在一个 Stack 中:

基本演示。

基本演示 2。

Row(
  children: [
    const Text('Tap the icon'),
    HitSlopBuilder(
      slop: const EdgeInsets.all(8),
      builder: (context, hitBox) => GestureDetector(
        onTap: () {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Pressed'),
              behavior: SnackBarBehavior.floating,
            ),
          );
        },
        child: Container(
          color: Colors.green.withOpacity(0.2),
          child: hitBox,
        ),
      ),
      child: const Icon(
        Icons.add,
        color: Colors.black,
        size: 24,
      ),
    ),
  ],
);

它通过使用 OverlayEntry 在底层小部件上浮置点击范围来实现这一点。


示例代码

import 'package:flutter/material.dart';
import 'package:hit_slop/hit_slop.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Builder(
          builder: (context) {
            return Center(
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text('Tap the icon'),
                  HitSlopBuilder(
                    slop: const EdgeInsets.all(8),
                    builder: (context, hitBox) => GestureDetector(
                      onTap: () {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text('Pressed'),
                            behavior: SnackBarBehavior.floating,
                          ),
                        );
                      },
                      child: Container(
                        color: Colors.green.withOpacity(0.2),
                        child: hitBox,
                      ),
                    ),
                    child: const Icon(
                      Icons.add,
                      color: Colors.black,
                      size: 24,
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

更多关于Flutter触摸区域调整插件hit_slop的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter触摸区域调整插件hit_slop的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


hit_slop 是 Flutter 中用于调整触摸区域的一个常用技巧。它允许你扩展或缩小一个 Widget 的触摸区域,而不影响其实际布局。这对于提高用户体验,尤其是在小尺寸或触摸目标难以准确点击的情况下非常有用。

使用 hit_slop 的基本方法

在 Flutter 中,hit_slop 并不是一个独立的插件,而是通过 GestureDetectorInkWell 等 Widget 的 behavior 属性来实现的。你可以通过设置 behavior 属性为 HitTestBehavior.opaqueHitTestBehavior.deferToChildHitTestBehavior.translucent 来控制触摸行为。

1. 使用 GestureDetector

GestureDetector(
  behavior: HitTestBehavior.opaque, // 控制触摸行为
  onTap: () {
    print('Tapped!');
  },
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
    child: Center(child: Text('Tap Me')),
  ),
)

2. 使用 InkWell

InkWell(
  onTap: () {
    print('Tapped!');
  },
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
    child: Center(child: Text('Tap Me')),
  ),
)

扩展触摸区域

如果你想要扩展触摸区域,可以使用 PaddingContainer 来包裹你的 Widget,从而增加触摸区域。

GestureDetector(
  onTap: () {
    print('Tapped!');
  },
  child: Padding(
    padding: EdgeInsets.all(20), // 扩展触摸区域
    child: Container(
      width: 100,
      height: 100,
      color: Colors.blue,
      child: Center(child: Text('Tap Me')),
    ),
  ),
)

缩小触摸区域

如果你想要缩小触摸区域,可以使用 ClipRect 或其他裁剪 Widget 来限制触摸区域。

GestureDetector(
  onTap: () {
    print('Tapped!');
  },
  child: ClipRect(
    child: Container(
      width: 100,
      height: 100,
      color: Colors.blue,
      child: Center(child: Text('Tap Me')),
    ),
  ),
)

使用 hitTest

如果你需要更精细的控制,可以重写 hitTest 方法来自定义触摸区域。

class CustomHitTestWidget extends SingleChildRenderObjectWidget {
  const CustomHitTestWidget({Key? key, required Widget child}) : super(key: key, child: child);

  [@override](/user/override)
  RenderObject createRenderObject(BuildContext context) {
    return CustomHitTestRenderObject();
  }
}

class CustomHitTestRenderObject extends RenderProxyBox {
  [@override](/user/override)
  bool hitTest(BoxHitTestResult result, {required Offset position}) {
    // 自定义触摸区域
    if (size.contains(position)) {
      result.add(BoxHitTestEntry(this, position));
      return true;
    }
    return false;
  }
}
回到顶部