recyclerview 分割线(去掉头和尾部)

来源:互联网 发布:房屋平面设计图软件 编辑:程序博客网 时间:2024/05/17 00:18


转载请注明出处:http://write.blog.csdn.net/postedit/78753985本文出自:【男儿当自强】



概述

RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。 
据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView、GridView。

那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

  • 你想要控制其显示的方式,请通过布局管理器LayoutManager
  • 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
  • 你想要控制Item增删的动画,请通过ItemAnimator
  • 你想要控制点击、长按事件,请自己写

基本使用

鉴于我们对于ListView的使用特别的熟悉,对比下RecyclerView的使用代码:

mRecyclerView = findView(R.id.id_recyclerview);//设置布局管理器mRecyclerView.setLayoutManager(layout);//设置adaptermRecyclerView.setAdapter(adapter)//设置Item增加、移除动画mRecyclerView.setItemAnimator(new DefaultItemAnimator());//添加分割线mRecyclerView.addItemDecoration(new DividerItemDecoration(                getActivity(), DividerItemDecoration.HORIZONTAL_LIST));

RecycleView 默认情况使用系统默认的添加分割线类(DividerItemDecoration) 添加分割线,是在每个item下面添加一个分割线。在某些时候,我们是不希望每个item下面都添加一个分割线,比如第一个View作为RecycleView  的HeaderView的时候,我们不希望HeaderView有任何分割线。最后一个Item也不希望出现分割线(实际上看起来也很不爽)

我们查看系统默认的添加分割线的类(DividerItemDecoration)关键代码如下:

private void drawVertical(Canvas canvas, RecyclerView parent) {        canvas.save();        final int left;        final int right;        //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.        if (parent.getClipToPadding()) {            left = parent.getPaddingLeft();            right = parent.getWidth() - parent.getPaddingRight();            canvas.clipRect(left, parent.getPaddingTop(), right,                    parent.getHeight() - parent.getPaddingBottom());        } else {            left = 0;            right = parent.getWidth();        }        final int childCount = parent.getChildCount();for (int i = 0; i < childCount; i++) {        final View child = parent.getChildAt(i);        parent.getDecoratedBoundsWithMargins(child, mBounds);        final int bottom = mBounds.bottom + Math.round(child.getTranslationY());        final int top = bottom - mDivider.getIntrinsicHeight();        mDivider.setBounds(left, top, right, bottom);        mDivider.draw(canvas);}        canvas.restore();    }



上面标红的代码是为每个item画一条分割线。我们就可以在这个方法 里面做文章了

通过日志调试可以知道  parent.getChildCount()方法得到的是,当前屏幕内的子视图的数量。

那么我们不希望屏幕最后一个Item不出现分割线,那么我们可以让他少画一个就可以了(少执行一个for循环即可)

private void drawVertical(Canvas canvas, RecyclerView parent) {        canvas.save();        final int left;        final int right;        //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.        if (parent.getClipToPadding()) {            left = parent.getPaddingLeft();            right = parent.getWidth() - parent.getPaddingRight();            canvas.clipRect(left, parent.getPaddingTop(), right,                    parent.getHeight() - parent.getPaddingBottom());        } else {            left = 0;            right = parent.getWidth();        }        final int childCount = parent.getChildCount();for (int i = 0; i < childCount - 1; i++) {        final View child = parent.getChildAt(i);        parent.getDecoratedBoundsWithMargins(child, mBounds);        final int bottom = mBounds.bottom + Math.round(child.getTranslationY());        final int top = bottom - mDivider.getIntrinsicHeight();        mDivider.setBounds(left, top, right, bottom);        mDivider.draw(canvas);}        canvas.restore();    }

当然这是一种投机取巧的方式,效果也是可以实现的。用同样的方式去掉第一个Item下面的分割线就不可以了。因为 这段代码处理的只是当前屏幕内的View

那么如果去掉第一个Item下面的分割线呢?(看官请慢慢往下看)

思路:我要找到第一个子View所在的Position,判断这个位置是不是0即可(position ==0), 如果是这个位置,就跳过,不让它画线

通过查看RecyclerView源码方法。我找到一个方法 getChildLayoutPosition看到方法名字可以猜测这个方法是获取子视图所在的位置position,通过日志测试可以知道,确实是我们想要的方法,那么我们就可以通过这个方法得到我们想要的位置了,具体代码如下:

int pos = parent.getChildLayoutPosition(parent.getChildAt(i));

到这儿问题就可以解决了。下面贴上修改完后完整的代码:

private void drawVertical(Canvas canvas, RecyclerView parent) {        canvas.save();        final int left;        final int right;                //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.        if (parent.getClipToPadding()) {            left = parent.getPaddingLeft();            right = parent.getWidth() - parent.getPaddingRight();            canvas.clipRect(left, parent.getPaddingTop(), right,                    parent.getHeight() - parent.getPaddingBottom());        } else {            left = 0;            right = parent.getWidth();        }        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount - 1; i++) {       // 获取当前子试图所在的位置        int pos = parent.getChildLayoutPosition(parent.getChildAt(i));        // 跳过这个item不画线        if(i == 0 && pos == 0){    continue;        }        final View child = parent.getChildAt(i);        parent.getDecoratedBoundsWithMargins(child, mBounds);        final int bottom = mBounds.bottom + Math.round(child.getTranslationY());        final int top = bottom - mDivider.getIntrinsicHeight();        mDivider.setBounds(left, top, right, bottom);        mDivider.draw(canvas);        }                                                                                                                                                 canvas.restore();    }


这样的话, 你可以控制去掉任何一个ItemView下面的分割线了











原创粉丝点击