一:概述
前一篇博客说了listview中的adapter中装多个adapter的方式解决scrollview嵌套listview的方式,这篇就说nestscrolling+recycleview的方式解决问题。
效果图:
二:预备知识
首先我们先了解下NestedScrollingChild 和 NestedScrollingParent
子布局中需要实现NestedScrollingChild接口 并且需要有个NestedScrollingChildHelper 成员变量,实现接口后需要实现一些方法,方法中调用NestedScrollingChildHelper 对应的方法即可。
比如:
@Override
public void stopNestedScroll() {
childHelper.stopNestedScroll();
}
其他方法类似即可。
需要重点说一下onTouchEvent()方法。
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//开始滑动:startNestedScroll(ViewCompat.SCROLL_AXIS_HORIZONTAL|ViewCompat.SCROLL_AXIS_VERTICAL);
break;
case MotionEvent.ACTION_MOVE:
//将事件分发给父布局中
if (dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)) {
dx -= consumed[0];
dy -= consumed[1];
}
case MotionEvent.ACTION_UP:
//停止滑动
stopNestedScroll();
break;
}
在action_down,action_up中调用开始,停止滑动的方法。
dx -= consumed[0]; consumed[0]是父布局中消耗的x方向上的位移。
dy -= consumed[1]; consumed[1]是父布局中消耗的y方向上的位移。
然后dx,dy就可以自己使用了。
父布局中需要实现NestedScrollingParent 接口 实现这个接口的类中需要NestedScrollingParentHelper 成员变量并且需要实现一些方法。
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return true;
}
@Override
public void onNestedScrollAccepted(View child, View target, int axes) {
parentHelper.onNestedScrollAccepted(child, target, axes);
}
@Override
public void onStopNestedScroll(View child) {
parentHelper.onStopNestedScroll(child);
}
onStartNestedScroll 返回true ,NestedScrollingChild 和 NestedScrollingParent 的关系才能有意义。
//子布局中分发过来的事件就可以在这里面进行处理。将自己消耗掉的位移加给consumed[0],consumed[1]就可以了。
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
}
好了通过上面的讲解,基本可以使用NestedScrollingChild 和 NestedScrollParent了。
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild{
}
因为RecyclerView 已经实现了NestedScrollingChild,我们就只用管ParentView了。
如图,上面是一个headerview,下面就是recycleview,这二者组合成了一个parentview
<?xml version="1.0" encoding="utf-8"?>
<com.example.tongmin.nestscrollingandrecyleview.ParentView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:background="#8C9BEB"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.example.tongmin.nestscrollingandrecyleview.ParentView>
当我们在向上滑动的过程中,判断headerView是否已经完全消失不见了,如果没有,那么就让parentview整体向上滑动。
注意: 因为parentview整体向上滑动那么recycleview肯定随着parentview一起向上滑动,但是parentview的高度是match_parent,向上滑动后下面就会“走光”了。
如图:
所以这里需要处理的是,在向上滑动的时候需要动态的将parentview的高度增高一次。
ViewGroup.LayoutParams params = this.getLayoutParams();
params.height = headerHeight+this.getHeight();
this.setLayoutParams(params);
requestLayout();
而这个增加的高度就是headerview的高度。并且后面也不用减回来了。
加个好友共同学习(不是公众号):
因为小弟水平有限,如果有写的有问题,希望指出。