首页 > 解决方案 > 在 RecyclerView 中拦截触摸事件,同时忽略内部的 EditText

问题描述

我有 recyclerView 和项目,如下所示:

list_row_item

现在我希望能够单击项目上的任何位置,并且 editText 应该成为焦点。我可以通过这样设置onTouchListener我的视图来做到这一点:

row_item.setOnTouchListener{ _, _ ->
            editText.requestFocus()
            view.background = Color.GREEN.toDrawable()
            true
        }

每当单击该项目时,我还想运行一些附加代码。在这里,为了示例,我将更改背景颜色。

问题是,每当我单击 editText 本身时,它都会获得焦点,但 row_item touchListener 会被忽略,并且背景不会改变其颜色。

根据我的研究,我发现我应该以某种方式拦截触摸事件。我想我可以通过在 row_item.setOnTouchListener 中返回 true 来做到这一点,但正如你所见,它不起作用。

我怎样才能拦截这样的触摸事件?

标签: androidkotlin

解决方案


您应该创建一个自定义容器类,然后覆盖onInterceptTouchEvent方法并在那里做您的事情,然后使用这个自定义容器类作为项目的根。看下面的代码:

class CustomFrameLayout : FrameLayout {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

    private var mOnInterceptTouchEventListener: OnTouchListener? = null

    fun setOnInterceptTouchEventListener(onInterceptTouchEventListener: OnTouchListener) {
        this.mOnInterceptTouchEventListener = onInterceptTouchEventListener
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        if(mOnInterceptTouchEventListener != null && mOnInterceptTouchEventListener?.onTouch(this, ev) == true)
            return true;
        return super.onInterceptTouchEvent(ev)
    }
}

然后将此侦听器添加到您的row_item

row_item.setOnInterceptTouchEventListener(object: View.OnTouchListener {
    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        editText.requestFocus()
        v?.background = Color.GREEN.toDrawable()
        return false
    }
})

这可能不是最好的答案,但它有效。


推荐阅读