RecyclerView滑动距离计算 包含多个Header的万能开挂情况

昨天项目中使用recycleView之后,有一个吸顶的显示条,需要判断当前已经滑动距离。
当滑动超过某个View之后吸顶的条目就需要出现,
首先获取吸顶条目出现条件的item的高度,

public void getXDtop(){
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                xDtop = iv_XXX.getTop();
            }
        });
    }

于是在网上找到了
http://blog.csdn.net/qq_25280063/article/details/50955758

http://blog.csdn.net/wangbaochu/article/details/49446469

public int getScollYDistance() {  
    LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();  
    int position = layoutManager.findFirstVisibleItemPosition();  
    View firstVisiableChildView = layoutManager.findViewByPosition(position);  
    int itemHeight = firstVisiableChildView.getHeight();  
    return (position) * itemHeight - firstVisiableChildView.getTop();  
}  

带入代码之后发现吸顶部分会先显示然后再次消失,debug发现互动距离变大然后又变小了。
读了一下代码,意思是获取当前展示position然后乘上每个Item的高度再加上当前可见item的getTop
,而没有考虑添加header的情况,导致header消失之后,计算完全错误。
之后自己修正为

    int headerHeight;
    private int getDistance(){
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getRecyclerView().getLayoutManager();
        // 获取第一个可见item的位置
        int position = layoutManager.findFirstVisibleItemPosition();

        if (position == 0) {
            // 获取header
            View headerView = layoutManager.findViewByPosition(0);
            // 获取第一个可见item的高度
            headerHeight = headerView.getHeight();
        }

        // 获取第一个可见item
        View firstVisiableChildView = layoutManager.findViewByPosition(position);
        // 获取第一个可见item的高度
        int itemHeight = firstVisiableChildView.getHeight();
        // 获取第一个可见item的位置
        int distance = 0;
        if (position == 0) {
            distance = (position) * itemHeight - firstVisiableChildView.getTop();
        } else {
            distance = (position) * itemHeight - firstVisiableChildView.getTop() + headerHeight;
        }

        return distance;
    }

然后就可在srcollListener中使用了

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);

                    LogUtils.e("scrollview_home.addOnScrollListener");
                    if (getDistance() == getDistanceToTop()) {
                        。。。。。。。
                    }

                    if (getDistance() < xDtop && getDistance() > 0 && xDtop > 0) {
                    。。。。。。。。
                    }
                }
            });

然后考虑header有多个的情况,这个着实废了一番功夫,因为逻辑比较绕,主要是记录所有Header的高度,然后根据当前显示的position去计算小于position的所有Header的高度总和,直接上代码

   Integer[] headerHeightArray;
    private int getDistanceToTop(){
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getRecyclerView().getLayoutManager();
        // 获取第一个可见item的位置
        int position = layoutManager.findFirstVisibleItemPosition();
        // 获取第一个可见item
        View firstVisiableChildView = layoutManager.findViewByPosition(position);

        // 必须考虑有没有Header  预存下所有header的高度
        int headerCount = adapter.getHeaderCount();
        if (headerCount > 0) {
            if (headerHeightArray == null) {
                headerHeightArray = new Integer[headerCount];
            }
            if (position < headerCount) {
                View headerView_i = layoutManager.findViewByPosition(position);
                headerHeightArray[position] = headerView_i.getHeight();
            }
        }

        // 获取第一个可见item的高度
        int itemHeight = firstVisiableChildView.getHeight();
        // 获取第一个可见item的位置
        int distance = 0;
        if (position == 0) {
            distance = (position) * itemHeight - firstVisiableChildView.getTop();
        } else {
            int allHeaderHeight = 0;
            for (int i = 0; i < position; i++) {
                allHeaderHeight = allHeaderHeight + headerHeightArray[i];
            }
            distance = (position) * itemHeight - firstVisiableChildView.getTop() + allHeaderHeight;
        }
        return distance;
    }

各位码农朋友,谨奉上,笑纳。

你可能感兴趣的:(android,java)