1. ホーム
  2. android

[解決済み] RecyclerView + AppBarLayoutでフライングする

2022-04-22 10:43:47

質問

私はAppBarLayoutとCollapsingToolbarLayoutと新しいCoordinatorLayoutを使用しています。AppBarLayoutの下に、私はコンテンツのリストを持つRecyclerViewを持っています。

RecyclerViewでリストを上下にスクロールする際に、フリングスクロールが動作することを確認しました。しかし、拡張時にAppBarLayoutもスムーズにスクロールさせたいと思っています。

CollaspingToolbarLayoutを展開するために上にスクロールするとき、画面から指を離すとすぐにスクロールが停止してしまいます。素早い動きで上にスクロールすると、CollapsingToolbarLayoutも再縮小することがあります。RecyclerViewでのこの動作は、NestedScrollViewを使用した場合とは、かなり異なる機能であるように思われます。

recyclerviewにいろいろなスクロールプロパティを設定してみましたが、これといった解決策がありません。

スクロールの問題の一部を動画で紹介します。 https://youtu.be/xMLKoJOsTAM

以下は、RecyclerView(CheeseDetailActivity)の問題を示す例です。 https://github.com/tylerjroach/cheesesquare

Chris Banes氏のNestedScrollViewを使用したオリジナル例です。 https://github.com/chrisbanes/cheesesquare

解決方法は?

の答えは キリル・ボヤルシノフ はほぼ正解でした。

主な問題は、RecyclerViewが時々間違った方向を示すことです。彼の答えに次のコードを追加すると、正しく動作します。

public final class FlingBehavior extends AppBarLayout.Behavior {
    private static final int TOP_CHILD_FLING_THRESHOLD = 3;
    private boolean isPositive;

    public FlingBehavior() {
    }

    public FlingBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
        if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
            velocityY = velocityY * -1;
        }
        if (target instanceof RecyclerView && velocityY < 0) {
            final RecyclerView recyclerView = (RecyclerView) target;
            final View firstChild = recyclerView.getChildAt(0);
            final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
            consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
        }
        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        isPositive = dy > 0;
    }
}

お役に立てれば幸いです。