web-dev-qa-db-ja.com

スクロール時にCoordinatorLayoutのRecyclerViewで機能しないをクリックします

AppBarLayoutの直後にあるCoordinatorLayoutの2番目の子としてのRecyclerViewで、奇妙な動作に直面しています(多くの例で説明されています)。

私の問題は、リサイクラービューをスクロールして、特定のアイテムをクリックしたいときです。そのアイテムを選択するために2回クリックする必要がある場合がありますが、これはフリングの動作に関連しているようです。たとえば、リサイクラービューの一番下までスクロールした場合、画面の一番下から一番上に指を投げると(より多くのデータを表示するためですが、私の場合は、すでに一番下にあります)そしてすぐにアイテムをクリックすると、フリングが停止しているように見え、2回目のクリックで実際にアイテムが選択されます... CoordinatorLayoutなしの単純なリサイクラービューを使用している場合、この動作は明らかに発生しません。

私のrecyclerviewは、文字列の単純なリストを保持し、次のレイアウト動作を使用しています:@ string/appbar_scrolling_view_behavior

理由はわかりますか?

[編集] Android Studioサンプルのスクロールアクティビティを試してみましたが、Googleサポートリポジトリのバグのようです。実際、サポートバージョン26.1.Oを使用している場合(26.0と同じ) .0および26.0.2)、私が話しているバグは存在しますが、バージョン26.0.0-alpha1または26.0.0-beta1で試してみると、実際に機能しています...

これに関してGoogleには2つの未解決のバグがあります: https://issuetracker.google.com/u/1/issues/66996774https://issuetracker.google.com/u/ 1/issues/68077101

同じ問題に直面している場合は、これらのバグにスターを付けてください

14
gxela

Googleはこのバグの回避策を投稿したばかりで、後で公開される予定です。

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

15
gxela

NestedScrollViewでRecyclerViewを使用する場合は、次の行をRecyclerViewに追加します。

Android:nestedScrollingEnabled="false"

お役に立てば幸いです。

3
Alireza K

私もこの問題を見つけました...さまざまなことを検索して試したのに何時間も無駄にした後、私はトリックを思いつきました、それはきれいではありませんが、それは他の誰かのためにも働くことができました。

基本的には、nestedScrollViewのクリックをシミュレートするという考え方です。

私の場合、完全に展開された「AppBarLayout」を検出した後、ネストされたものにタップを送信します。

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);
}

注:このようなハックの使用はお勧めしません。専門的ではなく、保守もできませんが、知っているほど...

0
Blaaz