API 26にアップグレードし、ライブラリ26.0.2をサポートしました。しかし、スクロールした直後にRecyclerView
アイテムをクリックできないことがわかりました。しばらく待つと動作します。ただし、すぐにアイテムをクリックしても、クリックされません。 RecyclerView
がまったくスクロールしていない場合でも(たとえば、一番上までスクロールした場合)。
ライブラリ25.4.0をサポートするためにダウングレードしたとき、すべてが再びうまくいきます。重要な点は、私のRecyclerView
がCoordinatorLayout
にあり、Toolbar
のAppBarLayout
に_SCROLL_FLAG_SCROLL
_フラグがあることです。このフラグを使用しないと、この問題はなくなります。だから、サポートライブラリ26の隠された動作の変更だと思います。
_focusable="false"
_をCoordinatorLayout
に追加しようとしましたが、まだ運がありませんでした。
この動作を無効にする方法はありますか?クリックイベントをトリガーするために2回クリックするのは本当に面倒だからです。
_ <Android.support.design.widget.CoordinatorLayout
Android:id="@+id/coordinateLayout"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/fragmentAppBar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:elevation="0dp"
Android:background="@null">
<include
Android:id="@+id/dynamicActionBarHolder"
layout="@layout/dynamic_action_bar"/>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.widget.SwipeRefreshLayout
Android:id="@+id/pullToRefreshMailRecycler"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/mailRecyclerView"
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
</Android.support.v4.widget.SwipeRefreshLayout>
</Android.support.design.widget.CoordinatorLayout>
_
編集
問題はscrollState
のRecyclerView
であると思います。スクロールを停止しても、すぐに_SCROLL_STATE_IDLE
_に変更されません。 RecyclerView
のソースコードを見ると、スクロール状態を制御するViewFlinger
があることがわかりました。上にスクロールしてスクロールすると、すぐにsetScrollState(SCROLL_STATE_IDLE)
が呼び出されず、代わりにこのメソッドがトリガーされるまでしばらく待機します。早く逃げるほど、待つ時間が長くなります。 RecyclerViewがまだバックグラウンドでスクロールしているようです。 scroller.isFinished()
は、RecyclerView
が上部に触れたときにスクロールを停止した直後にtrueを返さないためです。 RecyclerView
にあるCoordinatorLayout
のバグかもしれません。
スクロール状態を強制的にアイドルにする方法を見つけました。 Googleがこのバグを修正するのを待っています。
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean requestCancelDisallowInterceptTouchEvent = getScrollState() == SCROLL_STATE_SETTLING;
boolean consumed = super.onInterceptTouchEvent(event);
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
if( requestCancelDisallowInterceptTouchEvent ){
getParent().requestDisallowInterceptTouchEvent(false);
// only if it touched the top or the bottom. Thanks to @Sergey's answer.
if (!canScrollVertically(-1) || !canScrollVertically(1)) {
// stop scroll to enable child view to get the touch event
stopScroll();
// do not consume the event
return false;
}
}
break;
}
return consumed;
}
編集
この問題は、サポートライブラリ27.0.1で修正されました。
https://developer.Android.com/topic/libraries/support-library/revisions.html#27-0-1
ユーザーがスクロールした後、RecyclerViewのアイテムをクリックすることはできません。 (AOSP問題66996774)
2017年11月17日に更新
一部のユーザーは、この問題はサポートライブラリ27.0.1では修正されていないと報告しました。問題追跡ツールはこちらです。 https://issuetracker.google.com/issues/66996774
したがって、この公式の回避策を使用することもできます。 https://Gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2
または、こちらを使用してください。
この質問と回答をありがとうございました!それは私に多くの時間を節約しました。これを回答として投稿してすみません。コメントするのに十分な評判がありません。
この問題にも気づきましたが、新しいAndroid開発者として、新しいサポートライブラリ内のバグであることに気付きませんでした。
私が提案したかったのは、このチェックを追加することでもあります:
if( requestCancelDisallowInterceptTouchEvent ){
if (!canScrollVertically(-1) || !canScrollVertically(1)) {
...
}
}
RecyclerViewが実際にスクロールされている間、アイテムをクリックしないようにします。
私が理解しているように、それは予想される動作です。しかし、あなたの答えはこれを助けてくれました question 。
この問題を解決するソースコードを見つけました。この問題は、AppBarLayoutの動作(AppBarLayout.Behavior)が原因で発生します。このソースコードは、AppBarLayoutの動作の拡張またはカスタマイズ動作を提供し、xmlまたはJavaの両方での使用を導入してAppBarLayoutに設定します。ソースにはあなたにも読まなければならないライセンスがあるので、私はそれについて簡単に説明するだけです。このリンクの解決策を参照してください: https://Gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2