在使用 RecyclerView 进行滚动时,通过定时器实现自动滚动,但在滚动中无法正确触发 item 的点击事件。
因为RecyclerView 滚动与点击事件是独立的,默认情况下,滚动操作可能会影响点击事件的传递。
解决方案
1. 使用 Handler 替代 Timer
在 Android 中,使用 Handler 更适合处理定时任务。替换原有的 Timer 实现,改用 Handler 来处理滚动任务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | private Handler mHandler = new Handler(); private Runnable mScrollTask;
 
  mScrollTask = new Runnable() {     @Override     public void run() {         rvWidget.smoothScrollBy(6, 0);         mHandler.postDelayed(this, 30);      } };
 
  mHandler.postDelayed(mScrollTask, 0);
 
  mHandler.removeCallbacks(mScrollTask);
   | 
 
2. 处理点击事件
为了在滚动中也能触发 item 的点击事件,对 RecyclerView 进行自定义处理。使用一个自定义的 RecyclerView 类,通过重写 dispatchTouchEvent 方法,在滚动中模拟点击事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | public class CustomRecyclerView extends RecyclerView {     private boolean isScrolling = false;     private float downX;
      @Override     public boolean dispatchTouchEvent(MotionEvent ev) {         switch (ev.getAction()) {             case MotionEvent.ACTION_DOWN:                 downX = ev.getX();                 isScrolling = true;                  break;             case MotionEvent.ACTION_MOVE:                 isScrolling = true;                 break;             case MotionEvent.ACTION_UP:                 float upX = ev.getX();                 float deltaX = Math.abs(upX - downX);                 if (isScrolling && deltaX <= 30) {                                          View child = findChildViewUnder(ev.getX(), ev.getY());                     if (child != null) {                         int position = getChildAdapterPosition(child);                         if (position != RecyclerView.NO_POSITION) {                             getAdapter().onBindViewHolder(                                     (ViewHolder) findViewHolderForAdapterPosition(position),                                     position);                             performItemClick(child);                         }                     }                 }                 isScrolling = false;                 break;         }         return super.dispatchTouchEvent(ev);     }
      private void performItemClick(View view) {         if (view != null) {             view.performClick();         }     } }
  | 
 
最终通过使用 Handler 处理定时任务和自定义 RecyclerView 处理点击事件,实现了在滚动中仍能正确触发 item 点击事件的效果。