Android使用TouchDelegate增加View的触摸范围

 更新时间:2018年05月26日 11:42:04   作者:sgwhp  
这篇文章主要为大家详细介绍了Android使用TouchDelegate增加View的触摸范围,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文为大家分享了Android使用TouchDelegate增加View触摸范围的方法,供大家参考,具体内容如下

还不知道TouchDelegate这个东西的可以先看一下API,这里大致说一下它的作用:假设有两个View,分别是v1,v2,我们可以通过v1的setTouchDelegate(bounds, v2)来委派触摸事件,其中bounds是一个Rect。v1中,落在这个范围的TouchEvent都会传给v2。

既然是这样,那我们可以通过设置某个view的parent的touchDelegate来达到扩大这个view触摸范围的目的。关键是什么时候去执行parent.setTouchDelegate()方法呢?要设置这个委派,必须得知道当前view大小以及它在parent的位置。而这些数据都是在onLayout才能确定(注:如果不是自定义View,只是在Activity中设置,请将这些操作置于onWindowFocusChanged()方法中)。至此,实现的思路已经很清晰了,我们通过自定义一个Button来检验一下,下面开始上代码:

为了方便在xml中使用我们自定义的View,并且可以自定义扩大的触摸范围,我们再自定义一个attrs,res/values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
  <declare-styleable name="LargeTouchableAreaView"> 
    <attr name="addition" format="dimension" /> 
    <attr name="additionBottom" format="dimension" /> 
    <attr name="additionLeft" format="dimension" /> 
    <attr name="additionRight" format="dimension" /> 
    <attr name="additionTop" format="dimension" /> 
  </declare-styleable> 
</resources> 

Button实现:

public class LargeTouchableAreasButton extends Button { 
  private final int TOUCH_ADDITION = 0; 
  private int mTouchAdditionBottom = 0; 
  private int mTouchAdditionLeft = 0; 
  private int mTouchAdditionRight = 0; 
  private int mTouchAdditionTop = 0; 
  private int mPreviousLeft = -1; 
  private int mPreviousRight = -1; 
  private int mPreviousBottom = -1; 
  private int mPreviousTop = -1; 
 
  public LargeTouchableAreasButton(Context context) { 
    super(context); 
  } 
 
  public LargeTouchableAreasButton(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(context, attrs); 
  } 
 
  public LargeTouchableAreasButton(Context context, AttributeSet attrs, 
      int defStyle) { 
    super(context, attrs, defStyle); 
    init(context, attrs); 
  } 
 
  private void init(Context context, AttributeSet attrs) { 
    TypedArray a = context.obtainStyledAttributes(attrs, 
        R.styleable.LargeTouchableAreaView); 
    int addition = (int) a.getDimension( 
        R.styleable.LargeTouchableAreaView_addition, TOUCH_ADDITION); 
    mTouchAdditionBottom = addition; 
    mTouchAdditionLeft = addition; 
    mTouchAdditionRight = addition; 
    mTouchAdditionTop = addition; 
    mTouchAdditionBottom = (int) a.getDimension( 
        R.styleable.LargeTouchableAreaView_additionBottom, 
        mTouchAdditionBottom); 
    mTouchAdditionLeft = (int) a.getDimension( 
        R.styleable.LargeTouchableAreaView_additionLeft, 
        mTouchAdditionLeft); 
    mTouchAdditionRight = (int) a.getDimension( 
        R.styleable.LargeTouchableAreaView_additionRight, 
        mTouchAdditionRight); 
    mTouchAdditionTop = (int) a.getDimension( 
        R.styleable.LargeTouchableAreaView_additionTop, 
        mTouchAdditionTop); 
    a.recycle(); 
  } 
 
  @Override 
  protected void onLayout(boolean changed, int left, int top, int right, 
      int bottom) { 
    super.onLayout(changed, left, top, right, bottom); 
    if (left != mPreviousLeft || top != mPreviousTop 
        || right != mPreviousRight || bottom != mPreviousBottom) { 
      mPreviousLeft = left; 
      mPreviousTop = top; 
      mPreviousRight = right; 
      mPreviousBottom = bottom; 
      final View parent = (View) this.getParent(); 
      parent.setTouchDelegate(new TouchDelegate(new Rect(left 
          - mTouchAdditionLeft, top - mTouchAdditionTop, right 
          + mTouchAdditionRight, bottom + mTouchAdditionBottom), this)); 
    } 
  } 
 
} 

然后在具体要使用到这个Button的xml中加上以下代码:

xmlns:lta="http://schemas.android.com/apk/res/com.xxx.xxx" 

其中"lta"这个名字可以随便取,最后的是你的app包名。
最后在这个Button中定义希望增大的尺寸:

<com.xxx.LargeTouchableAreasButton 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    lta:addition="30dp" /> 

大功告成。

但这个自定义的View并不是完美的,还存在以下问题:

1、必须保证parent足够大,如果自定义的范围超出parent的大小,则超出的那部分无效。

2、一个parent只能设置一个触摸委派,设置多个时,只有最后设置的child有效。如果希望一个view能设置多个委派,需要再自定义parent,具体方法可参考:链接地址

总而言之,要触发委派,必须保证parent接收到了触摸事件,并且落在了你定义的范围内。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android原生嵌入React Native详解

    Android原生嵌入React Native详解

    这篇文章主要为大家详细介绍了Android原生嵌入React Native的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • Android TreeView实现带复选框树形组织结构

    Android TreeView实现带复选框树形组织结构

    这篇文章主要为大家详细介绍了Android TreeView实现带复选框树形组织结构,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Android 内存优化知识点梳理总结

    Android 内存优化知识点梳理总结

    这篇文章主要介绍了Android 内存优化知识点梳理总结,Android 操作系统给每个进程都会分配指定额度的内存空间,App 使用内存来进行快速的文件访问交互,长时间如此便需要优化策略,文章分享优化知识点总结,需要的朋友可以参考一下
    2022-06-06
  • 详解Android中motion_toast的使用

    详解Android中motion_toast的使用

    我们通常会用 toast(也叫吐司)来显示提示信息,例如网络请求错误,校验错误等等。本文为大家介绍一个非常有趣的toast组件 —— motion_toast,感兴趣的可以了解一下
    2022-06-06
  • Android实现RecyclerView嵌套流式布局的详细过程

    Android实现RecyclerView嵌套流式布局的详细过程

    最近在做需求的时候,碰到有各种筛选项的界面,下面这篇文章主要给大家介绍了关于Android实现RecyclerView嵌套流式布局的详细过程,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Android实现微信分享带有缩略图的网页

    Android实现微信分享带有缩略图的网页

    最近做了一个web app的项目,要求分享web页还要带有图片功能,怎么实现呢?今天小编给大家分享android实现微信分享带有缩略图的网页功能,需要的朋友参考下
    2017-02-02
  • Android贝塞尔曲线初步学习第一课

    Android贝塞尔曲线初步学习第一课

    这篇文章主要为大家详细介绍了Android贝塞尔曲线初步学习的第一课,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Android仿微信联系人按字母排序

    Android仿微信联系人按字母排序

    但凡涉及到联系人界面,几乎都是按照字母排序的,那么联系人按字母排序是怎么实现的呢,下面小编就给大家详解Android仿微信联系人按字母排序,需要的朋友可以参考下
    2015-08-08
  • Flutter自动路由插件auto_route使用详解

    Flutter自动路由插件auto_route使用详解

    这篇文章主要为大家介绍了Flutter自动路由插件auto_route的基本使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Android自定义View实现两种二维码的扫描效果

    Android自定义View实现两种二维码的扫描效果

    这篇文章主要为大家详细介绍了Android如何自定义View实现两种二维码的扫描效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01

最新评论