最近有個需求,就是手指在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;
}
});