RecyclerView根据坐标得到position的思路

    技术2022-07-11  103

    最近有个需求,就是手指在RecyclerView随意滑动,如在ABCDEF 滑动到A就响应数据A显示。(当然该功能可以直接自定义view draw出来)效果如图

    核心即题目,RecyclerView根据坐标得到position?也就是说

    ACTION_DOWN,ACTION_MOVE的时候去实时回调position

    我们先直接给RecyclerView加上setOnTouchListener 得到x,y

    我一开始想到的方案1是根据item的宽高区域,去算出对应x,y所在position 但是并不好用,我试着猜想RecyclerView是否有自带的这个方法,联想ListView的setOnItemClick实现中有类似获取position的方法,但RecyclerView并没有自带setOnItemClick。

    我们position一般从哪儿拿呢,viewHolder.getAdapterPosition(),所以我们只要找到xy所在的item对应的viewHolder即可,x,y获取item的方法是自带的findChildViewUnder

    @Nullable public View findChildViewUnder(float x, float y) { int count = this.mChildHelper.getChildCount(); for(int i = count - 1; i >= 0; --i) { View child = this.mChildHelper.getChildAt(i); float translationX = child.getTranslationX(); float translationY = child.getTranslationY(); if (x >= (float)child.getLeft() + translationX && x <= (float)child.getRight() + translationX && y >= (float)child.getTop() + translationY && y <= (float)child.getBottom() + translationY) { return child; } } return null; }

    viewholder又如何从itemView里面得到呢查看源码

    public void bindViewToPosition(@NonNull View view, int position) { RecyclerView.ViewHolder holder = RecyclerView.getChildViewHolderInt(view); ... RecyclerView.LayoutParams rvLayoutParams; ... rvLayoutParams.mViewHolder = holder; } } }

    我们可以看到RecyclerView.getChildViewHolderInt 可以获取到holder。同时是赋值给了RecyclerView.LayoutParams

    RecyclerView.getChildViewHolderInt也是从RecyclerView.LayoutParams中取看有没有了

    所以得到触碰位置的position就比较容易了

    rv.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { View child = rv.findChildViewUnder(event.getX(), event.getY()); if (child != null) { RecyclerView.ViewHolder vh = rv.getChildViewHolder(child); mPosition = vh.getAdapterPosition(); } return true; } });

     

    Processed: 0.010, SQL: 9