Reputation: 28179
I have two activities using AppBarLayout
with a Toolbar
and TabLayout
from support library 22.
The layout of both is pretty similar: A Toolbar
at the top, below it TabLayout
, below it a ViewPager
containing 3 Fragment
s.
The first activity's Fragment
has a RecyclerView
,
the second activity's Fragment
is using a ListView
instead.
The scrollable Toolbar
example from https://github.com/chrisbanes/cheesesquare is working fine on the first activity using the RecyclerView
, but on with the ListView
.
I've tried created a custom ListViewScrollBehavior
that extends AppBarLayout.ScrollingViewBehavior
, but so far no luck.
The TouchEvent
s are passed to the custom class only for horizontal scrolling, but not when scrolling the ListView
(vertically).
Any way to use a CoordinatorLayout
with ListView
?
Upvotes: 34
Views: 19226
Reputation: 2548
You can add
android:nestedScrollingEnabled="true"
to the ListView
from XML, just note that this only supports API 21+. Alternatively, you can swap out your ListView
for a RecyclerView
, and that should work better.
Upvotes: 0
Reputation: 4644
ListView ScrollingViewBehavior supports only >= 21.
Otherwise you should to write code as below way:
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;
}
});
}
Upvotes: 1
Reputation: 331
To a view able to react on AppBarLayout, it need to implement NestedScrollingChild. ListView is not. But it could be implement by a delegate class easily. Use it, it will do like what RecyclerView did
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);
}
}
Upvotes: 6
Reputation: 12521
Alternative solution to Nicolas POMEPUY's answer is to use ViewCompat.setNestedScrollingEnabled(View, boolean)
ViewCompat.setNestedScrollingEnabled(listView, true);
Of course nested scrolling behavior will only work from Lollipop.
Upvotes: 14
Reputation: 1133
The only solution to make it work now is to use this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
listView.setNestedScrollingEnabled(true);
}
It will obviously only work on Lollipop.
Upvotes: 38
Reputation: 3677
I believe that the CoordinatorLayout
works only with RecyclerView
and NestedScrollView
. Try wrapping your ListView
in a NestedScrollView
or convert it to a RecyclerView
with a LinearLayoutManager
Upvotes: 11