美文网首页
Android扩大View点击区域[支持同时扩展多个子View]

Android扩大View点击区域[支持同时扩展多个子View]

作者: 寻水的鱼Chock | 来源:发表于2023-12-03 16:21 被阅读0次

    一年多前写过一篇文章, Android扩大View点击区域, 此方法存在诸多限制,且只能对其中一个子View进行点击范围的扩展, 今天想到一个新的思路, 实现并支持扩展任意多个子View的点击范围,供君参考(源码见文末)。

    使用实例
    binding.cv1.setOnClickListener {
        ToastUtils.show("cv1 Click!!")
    }
    val dp20 = 20.dpToPx() 
    ClickAreaExpander()
    .addExpandView(binding.cv1, dp20, dp20)
    //.addExpandView(binding.cv2, dp20, dp20)
    //.....
    .expandOn(binding.touchOutView)
    
    XML示例
    预览效果
    <FrameLayout
        android:id="@+id/touchOutView"
        android:layout_width="match_parent"
        android:layout_height="200dp">
    
        <View
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            android:background="#22000000" />
    
        <View
            android:id="@+id/cv1"
            android:layout_width="10dp"
            android:layout_height="10dp"
            android:layout_gravity="center"
            android:background="@drawable/shape_white_16" />
    
    </FrameLayout>
    
    源码实现
    class ClickAreaExpander : View.OnTouchListener {
    
        private var touchDelegates: MutableList<TouchDelegate> = mutableListOf()
        private var enable = false
        private var mItems = mutableListOf<Item>()
        lateinit var vg: ViewGroup
        var needInit = true
    
        fun expandOn(viewGroup: ViewGroup) {
            vg = viewGroup
            enable = true
            vg.setOnTouchListener(this)
        }
    
        /**
         * 增加需要扩宽点击范围的View
         *
         * @param view 扩充点击/长按事件的VIew
         * @param leftTop 扩宽距离,单位px
         * @param rightBottom 扩宽距离,单位px
         */
        fun addExpandView(view: View, leftTop: Int, rightBottom: Int): ClickAreaExpander {
            mItems.add(Item(view, leftTop, rightBottom))
            needInit = true
            return this
        }
    
        /**
         * 移除
         */
        fun removeView(view: View): ClickAreaExpander {
            mItems.firstOrNull { x -> x.view == view }?.let {
                mItems.remove(it)
                needInit = true
            }
            return this
        }
    
        override fun onTouch(v: View?, event: MotionEvent?): Boolean {
            event ?: return false
            v ?: return false
            var handle = false
            if (enable) {
                if (needInit) {
                    if (mItems.isEmpty()) {
                        enable = false
                        return false
                    }
                    initViews()
                }
                for (i in 0 until touchDelegates.size) {
                    val item = touchDelegates[i]
                    val h = item.onTouchEvent(event)
                    if (h) {
                        handle = true
                        break
                    }
                }
            }
            return handle
        }
    
        fun enable(e: Boolean = true) {
            enable = e
        }
    
        private fun initViews() {
            needInit = false
            touchDelegates.clear()
            mItems.forEach {
                val v = it.view
                if (vg.contains(v)) {
                    val rect = Rect()
                    v.getHitRect(rect)
                    rect.inset(-it.leftTop, -it.rightBottom)
                    touchDelegates.add(0, TouchDelegate(Rect(rect), v))
                }
            }
        }
    
        inner class Item(val view: View, val leftTop: Int, val rightBottom: Int)
    
    }
    
    如果本文对你有帮助就点个赞支持下吧~~~

    相关文章

      网友评论

          本文标题:Android扩大View点击区域[支持同时扩展多个子View]

          本文链接:https://www.haomeiwen.com/subject/bmokgdtx.html