对scrollview嵌套listview说不(二)NestedScrollingParent +RecyleView

一:概述

前一篇博客说了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的高度。并且后面也不用减回来了。

源码下载

加个好友共同学习(不是公众号):

这里写图片描述

因为小弟水平有限,如果有写的有问题,希望指出。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值