android - recyclerview - ScrollingViewBehavior para ListView
recyclerview android studio ejemplo (5)
Creo que CoordinatorLayout
solo funciona con RecyclerView
y NestedScrollView
. Intente envolver su ListView
en un NestedScrollView
o NestedScrollView
en un RecyclerView
con un LinearLayoutManager
Tengo dos actividades que usan AppBarLayout
con una Toolbar
y TabLayout
desde la biblioteca de soporte 22.
El diseño de ambos es bastante similar: una Toolbar
de Toolbar
en la parte superior, debajo de ella TabLayout
, debajo de ella una ViewPager
contiene 3 Fragment
.
El Fragment
la primera actividad tiene un RecyclerView
, el Fragment
la segunda actividad usa un ListView
lugar.
El ejemplo de Toolbar
desplazable de https://github.com/chrisbanes/cheesesquare funciona correctamente en la primera actividad que utiliza RecyclerView
, pero sigue con ListView
.
Intenté crear un ListViewScrollBehavior
personalizado que amplíe AppBarLayout.ScrollingViewBehavior
, pero hasta ahora no AppBarLayout.ScrollingViewBehavior
suerte. Los TouchEvent
s se pasan a la clase personalizada solo para desplazamiento horizontal, pero no al desplazarse por ListView
(verticalmente).
¿Alguna forma de utilizar un CoordinatorLayout
con ListView
?
La única solución para que funcione ahora es usar esto:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
listView.setNestedScrollingEnabled(true);
}
Obviamente solo funcionará en Lollipop.
ListView ScrollingViewBehavior solo admite> = 21.
De lo contrario, debe escribir el código de la siguiente manera:
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;
}
});
}
Para una vista capaz de reaccionar en AppBarLayout, necesita implementar NestedScrollingChild. ListView no lo es. Pero podría ser implementado por una clase de delegado fácilmente. Úselo, hará lo que hizo 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);
}
}
Una solución alternativa a la respuesta de Nicolas POMEPUY es usar ViewCompat.setNestedScrollingEnabled(View, boolean)
ViewCompat.setNestedScrollingEnabled(listView, true);
Por supuesto, el comportamiento de desplazamiento anidado solo funcionará desde Lollipop.