Click not working on RecyclerView in CoordinatorLa

2019-02-05 01:47发布

问题:

I am facing a strange behaviour with a RecyclerView as a second child of CoordinatorLayout, just after an AppBarLayout (as described in a lot of examples).

My problem is when I scroll the recycler view and I want to click on a particular item. Sometimes I need to click 2 times to select that item, it seems to be linked to the fling behaviour. For example, if I scrolled to the bottom of the recycler view, then if I fling my finger from the bottom of the screen to the top (in order to see more data, but in my case I can't see more data since I am already to the bottom) and then quickly click on an item, it seems to stop the fling, and the second click actually select the item... This behaviour is clearly not happening when using a simple recycler view without CoordinatorLayout.

My recyclerview is just holding a simple list of String, and using the following layout behaviour : @string/appbar_scrolling_view_behavior

Do you have any idea why ?

[EDIT] I just tried with the Android Studio sample Scrolling Activity, and it looks like it is a bug from Google support repository. In fact, when using support version 26.1.O (same with 26.0.0 and 26.0.2), the bug I am talking about is present, but if you try with the version 26.0.0-alpha1 or 26.0.0-beta1, it is actually working...

There is two open bugs at Google about this : https://issuetracker.google.com/u/1/issues/66996774 https://issuetracker.google.com/u/1/issues/68077101

Please star these bugs if you are facing the same problem

回答1:

Google just posted a workaround for this bug, it will be publicly released later.

https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2



回答2:

I also found this problem ... after wasting so many hours searching and trying different things, I came out with a trick, its not pretty but it could work for someone else too.

Basically the idea is simulate a click on the nestedScrollView.

In my case after I detect the 'AppBarLayout' its fully expanded, I send a tap to the nested.

protected void onCreate(final Bundle savedInstanceState) {

    getAppBarLayout().addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {

      @Override
      public void onOffsetChanged(final AppBarLayout appBarLayout, final int verticalOffset) {

          if (verticalOffset == 0) { 
              // State.EXPANDED
              simulatedClick(nestedScroll)
          } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) { 
              // State.COLLAPSED
          } else { 
              // State.IDLE
          }
      }
  });
}

private void simulatedClick(@NonNull final View view) {
    // Obtain MotionEvent object
    final long downTime = SystemClock.uptimeMillis();
    final long eventTime = SystemClock.uptimeMillis() + 100;
    final MotionEvent motionEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, 0.0f, 0.0f, 0);
    // Dispatch touch event to view
    view.dispatchTouchEvent(motionEvent);
}

NOTE: I don't really recommend the use of hacks like this, it's unprofessional and unmaintainable, but the more you know...