0

我试图向 itemdecoration 添加一个点击监听器,如下所示,但仍然没有运气。请帮忙。

recyclerview.addOnItemTouchListener( object : RecyclerView.OnItemTouchListener{
    override fun onTouchEvent(rv: RecyclerView?, e: MotionEvent?) {

    }

    override fun onInterceptTouchEvent(rv: RecyclerView?, e: MotionEvent?): Boolean {
        val view = rv!!.findChildViewUnder(e!!.x, e!!.y)
        if(view == null) return false
        when(view.id){
            R.id.list_item_section_text->{
                Log.d("Clicked","Header")
            }
        }
        return false
    }

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {

    }

})
4

2 回答 2

0

您可以自定义 RecyclerView 并检查触摸事件是否到达 ItemDecorator:

class YourRecyclerView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {

    private val clicksFlow: MutableSharedFlow<ClickEvent> = MutableSharedFlow(
        extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST
    )

    fun getClicksFlow() = clicksFlow as Flow<RecyclerClickEvent>

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(e: MotionEvent) : Boolean{
        if (e.action == MotionEvent.ACTION_DOWN) {
            for (i in 0 until itemDecorationCount) {
                val decor = getItemDecorationAt(i)
                if (decor is YourDecoration && decor.isOnTouched(this, e)) {
                    clicksFlow.tryEmit(ClickEvent(e.x, e.y))
                    return true
                }
            }
        }
        return super.onTouchEvent(e)
    }

    override fun onInterceptTouchEvent(e: MotionEvent): Boolean {
        if (e.action == MotionEvent.ACTION_DOWN) {
            for (i in 0 until itemDecorationCount) {
                val decor = getItemDecorationAt(i)
                if (decor is YourDecoration && decor.isOnTouched(this, e)) {
                    return true
                }
            }
        }
        return super.onInterceptTouchEvent(e)
    }
}

class YourDecoration(/*some stuff*/) : RecyclerView.ItemDecoration() {

    fun isOnTouched(parent: YourRecyclerView , e: MotionEvent): Boolean {
        val w = abs(scaleX * width)
        val h = abs(scaleY * height)
        val top = topMargin - height / 2F - parent.paddingTop
        return if (scaleX > 0) {
            val side = parent.measuredWidth - sideMargin
            e.y >= top && e.y <= (top + h) && side >= e.x && (side - w) <= e.x
        } else {
            val side = sideMargin
            e.y >= top && e.y <= (top + h) && side <= e.x && e.x <= (side + w)
        }
    }
}
于 2021-12-29T13:06:57.310 回答
0

ItemDecoration将帮助您在项目之间绘制一些东西,但View您正在绘制的实际上是RecyclerView它本身(根据布局检查器),通过它的Canvas. 因此,您将无法onClickListener在该装饰上添加基本内容。

根据您的代码,我猜您的每个项目标题都有一个项目装饰?

我会为此做的不是将我的标题视为一个项目,ItemDecoration而是将其视为一个项目(具有不同类型)RecyclerView

sealed class RecyclerViewItem
object MainItem : RecyclerViewItem()
object Header : RecyclerViewItem()

在您的适配器(带有项目:)中,RecyclerViewItem您使用自定义 ID 覆盖getItemViewType方法。然后,onBindViewHolder您可以检查项目视图类型,onClickListener如果它是Header.

有关更多信息,您可以搜索具有不同项目类型的构建 RecyclerView

于 2020-05-27T15:16:58.327 回答