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 Fragment
s.
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
?
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.
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.
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
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);
}
}
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;
}
});
}