问题来源
在5.0系统中新加入的nestedscrollview配合coordinatorlayout响应滚动事件,但在listview中没有相应的nested滚动接口,所以对coordinatorlayout中的一系列插件没有任何响应。
解决方法
一开始思路来源于
这篇博客,用一个自定义view继承想要实现滚动的view,实现nestedscrollingchild接口,通过nestedscrollingchildhelper类的方法来实现滚动响应。
public class NestedScrollingListView extends ListView implements NestedScrollingChild {
private final NestedScrollingChildHelper mScrollingChildHelper;
public NestedScrollingListView(Context context) {
super(context);
mScrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
public NestedScrollingListView(Context context, AttributeSet attrs) {
super(context, attrs);
mScrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mScrollingChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mScrollingChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mScrollingChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mScrollingChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mScrollingChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {
return mScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}
但是此方法只在5.0+系统中才能有效实现。
然后找到了
这篇博客,用一个nestedscrollview包裹在外层,来响应coordinatorlayout的滚动事件。
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<mddemo.materialdesigndemo.view.NestedListView
android:id="@+id/coordinator_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
//这里将listview的滚动事件去除,和nestedscrollview的滚动有冲突
public class NestedListView extends ListView {
public NestedListView(Context context) {
super(context);
}
public NestedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
在外侧的nestedscrollview响应和coordinatorlayout的滚动事件,就可以了。