Ответ 1
Единственное решение, с помощью которого оно теперь работает, - это следующее:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
listView.setNestedScrollingEnabled(true);
}
Очевидно, что он работает только на Lollipop.
У меня есть два действия с использованием AppBarLayout
с Toolbar
и TabLayout
из библиотеки поддержки.
Макет обоих довольно похож: A Toolbar
вверху, ниже него TabLayout
, под ним a ViewPager
, содержащий 3 Fragment
s.
Первая операция Fragment
имеет RecyclerView
,
вторая активность Fragment
использует вместо этого ListView
.
Прокручиваемый пример Toolbar
из https://github.com/chrisbanes/cheesesquare работает нормально в первом действии с помощью RecyclerView
, но с помощью ListView
.
Я пробовал создать пользовательский ListViewScrollBehavior
, который расширяет AppBarLayout.ScrollingViewBehavior
, но пока не повезло.
TouchEvent
передаются в пользовательский класс только для горизонтальной прокрутки, но не при прокрутке ListView
(по вертикали).
Как использовать CoordinatorLayout
с ListView
?
Единственное решение, с помощью которого оно теперь работает, - это следующее:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
listView.setNestedScrollingEnabled(true);
}
Очевидно, что он работает только на Lollipop.
Альтернативное решение Ответ Nicolas POMEPUY заключается в использовании ViewCompat.setNestedScrollingEnabled(View, boolean)
ViewCompat.setNestedScrollingEnabled(listView, true);
Конечно, вложенное поведение прокрутки будет работать только с Lollipop.
Я считаю, что CoordinatorLayout
работает только с RecyclerView
и NestedScrollView
. Попробуйте обернуть ListView
в NestedScrollView
или преобразовать его в RecyclerView
с помощью LinearLayoutManager
Для просмотра, способного реагировать на 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);
}
}
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;
}
});
}