web-dev-qa-db-ja.com

ListViewのScrollingViewBehavior

サポートライブラリ22からのAppBarLayoutおよびToolbarとともにTabLayoutを使用する2つのアクティビティがあります。

両方のレイアウトは非常に似ています:上部のToolbar、その下のTabLayout、その下の3つのViewPagersを含むFragment

最初のアクティビティのFragmentにはRecyclerViewがあり、2番目のアクティビティのFragmentは代わりにListViewを使用しています。

https://github.com/chrisbanes/cheesesquare のスクロール可能なToolbarの例は、RecyclerViewを使用する最初のアクティビティで正常に機能していますが、ListView

AppBarLayout.ScrollingViewBehaviorを拡張するカスタムListViewScrollBehaviorを作成しようとしましたが、これまでのところ運はありません。 TouchEventsは、水平スクロールの場合のみカスタムクラスに渡されますが、ListViewを(垂直に)スクロールする場合は渡されません。

CoordinatorLayoutListViewを使用する方法はありますか?

34
marmor

今それを機能させる唯一の解決策はこれを使用することです:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
     listView.setNestedScrollingEnabled(true);
}

それは明らかにロリポップでのみ動作します。

36
Nicolas POMEPUY

Nicolas POMEPUY's answer の代替ソリューションは、 ViewCompat.setNestedScrollingEnabled(View, boolean) を使用することです

ViewCompat.setNestedScrollingEnabled(listView, true);

もちろん、ネストされたスクロール動作はLollipopからのみ機能します。

13
hidro

CoordinatorLayoutRecyclerViewNestedScrollViewでのみ機能すると信じています。 ListViewNestedScrollViewをラップするか、RecyclerViewLinearLayoutManagerに変換してみてください

11
TheoK

AppBarLayoutに反応できるビューには、NestedScrollingChildを実装する必要があります。 ListViewはそうではありません。ただし、デリゲートクラスによって簡単に実装できます。それを使用すると、RecyclerViewがしたことのようになります

public class NestedScrollingListView extends ListView implements NestedScrollingChild {
private NestedScrollingChildHelper mNestedScrollingChildHelper;

public NestedScrollingListView(final Context context) {
    super(context);
    initHelper();
}

public NestedScrollingListView(final Context context, final AttributeSet attrs) {
    super(context, attrs);
    initHelper();
}

public NestedScrollingListView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initHelper();
}

@TargetApi(Build.VERSION_CODES.Lollipop)
public NestedScrollingListView(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    initHelper();
}

private void initHelper() {
    mNestedScrollingChildHelper = new NestedScrollingChildHelper(this);
    setNestedScrollingEnabled(true);
}

@Override
public void setNestedScrollingEnabled(final boolean enabled) {
    mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
}

@Override
public boolean isNestedScrollingEnabled() {
    return mNestedScrollingChildHelper.isNestedScrollingEnabled();
}

@Override
public boolean startNestedScroll(final int axes) {
    return mNestedScrollingChildHelper.startNestedScroll(axes);
}

@Override
public void stopNestedScroll() {
    mNestedScrollingChildHelper.stopNestedScroll();
}

@Override
public boolean hasNestedScrollingParent() {
    return mNestedScrollingChildHelper.hasNestedScrollingParent();
}

@Override
public boolean dispatchNestedScroll(final int dxConsumed, final int dyConsumed, final int dxUnconsumed, final int dyUnconsumed, final int[] offsetInWindow) {
    return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}

@Override
public boolean dispatchNestedPreScroll(final int dx, final int dy, final int[] consumed, final int[] offsetInWindow) {
    return mNestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}

@Override
public boolean dispatchNestedFling(final float velocityX, final float velocityY, final boolean consumed) {
    return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}

@Override
public boolean dispatchNestedPreFling(final float velocityX, final float velocityY) {
    return mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}

}

5
I Love Coding

ListView ScrollingViewBehaviorは21以上のみをサポートします。

それ以外の場合は、次の方法でコードを記述する必要があります。

private int mPreviousVisibleItem;


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
    listView.setNestedScrollingEnabled(true);
} else {
    listView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (firstVisibleItem > mPreviousVisibleItem) {
                appBarLayout.setExpanded(false, true);
            } else if (firstVisibleItem < mPreviousVisibleItem) {
                appBarLayout.setExpanded(true, true);
            }
            mPreviousVisibleItem = firstVisibleItem;
        }
    });
}
1