web-dev-qa-db-fra.com

ScrollingViewBehavior pour ListView

J'ai deux activités en utilisant AppBarLayout avec un Toolbar et TabLayout de la bibliothèque de support 22.

La disposition des deux est assez similaire: Un Toolbar en haut, en dessous TabLayout, en dessous un ViewPager contenant 3 Fragments.

Le Fragment de la première activité a un RecyclerView, le Fragment de la deuxième activité utilise un ListView à la place.

L'exemple de défilement Toolbar de https://github.com/chrisbanes/cheesesquare fonctionne bien sur la première activité en utilisant le RecyclerView, mais avec le ListView.

J'ai essayé de créer un ListViewScrollBehavior personnalisé qui étend AppBarLayout.ScrollingViewBehavior, mais jusqu'à présent, pas de chance. Les TouchEvent sont passés à la classe personnalisée uniquement pour le défilement horizontal, mais pas lors du défilement du ListView (verticalement).

Est-il possible d'utiliser un CoordinatorLayout avec ListView?

34
marmor

La seule solution pour le faire fonctionner maintenant est d'utiliser ceci:

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

Cela ne fonctionnera évidemment que sur Lollipop.

36
Nicolas POMEPUY

Une solution alternative à réponse de Nicolas POMEPUY est d'utiliser ViewCompat.setNestedScrollingEnabled(View, boolean)

ViewCompat.setNestedScrollingEnabled(listView, true);

Bien sûr, le comportement de défilement imbriqué ne fonctionnera que depuis Lollipop.

13
hidro

Je crois que le CoordinatorLayout ne fonctionne qu'avec RecyclerView et NestedScrollView. Essayez de mettre votre ListView dans un NestedScrollView ou de le convertir en RecyclerView avec un LinearLayoutManager

11
TheoK

Pour une vue capable de réagir sur AppBarLayout, elle doit implémenter NestedScrollingChild. ListView ne l'est pas. Mais il pourrait être facilement implémenté par une classe déléguée. Utilisez-le, il fera comme ce que RecyclerView a fait

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 ne prend en charge que> = 21.

Sinon, vous devez écrire le code comme ci-dessous:

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
Ahamadullah Saikat