RecyclerView中利用GridLayoutManager实现item四周都带有分割线效果(更正版!!!)

原创 2016年06月01日 23:41:54

今天,花了很长的时间才实现了如题的效果,回想一下,实现起来确实不难,只怪当时做的时候思路不清晰,没想好就动手了,这是病,得改!好了,不多说,实现工程中主要参考了鸿洋博客中Android RecyclerView 使用完全解析 体验艺术般的控件DividerGridItemDecoration这个类的实现,其中有一个问题,就是一开始我死活都弄不出竖向方向分割线效果,后来查了一下资料,最后在博客下方的评论那里找到了解决方案,即是:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:centerColor="#ff00ff00"
        android:endColor="#ff0000ff"
        android:startColor="#ffff0000"
        android:type="linear" />
    <size android:height="4dp"
        android:width="4dp"/>

</shape>

drawable文件中需要加上android:width=”4dp”这个属性,我在博客上面没看到有width这个属性,可能博客的demo里面有吧(这,就尴尬了,我这次没有下载源码来跑)。。
现在说一下如何实现item四周都带有分割线效果,关键地方在于DividerGridItemDecoration这个类,其中我作了修改的地方主要如下:

    public void drawHorizontal(Canvas c, RecyclerView parent)
    {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++)
        {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getLeft() - params.leftMargin;
            final int right = child.getRight() + params.rightMargin
                    + mDivider.getIntrinsicWidth();
            int top = 0;
            int bottom = 0;

            // 1  不计算中间item的divider情况
            if((i/column_num) == 0) {
                //画item最上面的分割线
                top = child.getTop(); //该处一开始是top = 0,没考虑到布局中recyclerview的padding情况
                bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
                //画item下面的分割线
                top = child.getBottom() + params.bottomMargin;
                bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
            else {
                top = child.getBottom() + params.bottomMargin;
                bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }

            // 2  计算中间item的divider情况
//            //画item最上面的分割线
//            top = child.getTop(); //该处一开始是top = 0,没考虑到布局中recyclerview的padding情况
//            bottom = top + mDivider.getIntrinsicHeight();
//            mDivider.setBounds(left, top, right, bottom);
//            mDivider.draw(c);
//            //画item下面的分割线
//            top = child.getBottom() + params.bottomMargin;
//            bottom = top + mDivider.getIntrinsicHeight();
//            mDivider.setBounds(left, top, right, bottom);
//            mDivider.draw(c);

        }
    }

    public void drawVertical(Canvas c, RecyclerView parent)
    {
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++)
        {
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getTop() - params.topMargin;
            final int bottom = child.getBottom() + params.bottomMargin;
            int left = 0;
            int right = 0;

            // 3  不计算中间item的divider情况
            if((i%column_num) == 0) {
                //item左边分割线
                left = child.getLeft();//该处一开始是left = 0,没考虑到布局中recyclerview的padding情况
                right = left + mDivider.getIntrinsicWidth();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
                //item右边分割线
                left = child.getRight() + params.rightMargin;
                right = left + mDivider.getIntrinsicWidth();
            }
            else {
                left = child.getRight() + params.rightMargin;
                right = left + mDivider.getIntrinsicWidth();
            }

            // 4  计算中间item的divider情况
//            //item左边分割线
//            left = child.getLeft();//该处一开始是left = 0,        没考虑到布局中recyclerview的padding情况
//            right = left + mDivider.getIntrinsicWidth();
//            mDivider.setBounds(left, top, right, bottom);
//            mDivider.draw(c);
//            //item右边分割线
//            left = child.getRight() + params.rightMargin;
//            right = left + mDivider.getIntrinsicWidth();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

代码里面我已经加上相应的注释,相信还是比较容易理解的,另外,屏蔽了如下的代码(下面的代码判断是否是最后一列,博主原本是不绘制右边的分割线):

private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
                                int childCount)
    {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
/*            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
            {
                return true;
            }*/
        } else if (layoutManager instanceof StaggeredGridLayoutManager)
        {

下面是判断是否是最后一行,博主原本是不绘制底部分割线

    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
                              int childCount)
    {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
/*             childCount = childCount - childCount % spanCount;
           if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
                return true;*/
        } else if (layoutManager instanceof StaggeredGridLayoutManager)
        {

实现的效果图,请忽视分割线太过花俏。。

备注:显示效果中出现了中间的item正常,但是边缘的item宽高别扭,主要是因为 我没有处理中间item的左、右divider造成,因为我的divider_bg中divider的width、height设置的比较小,不处理中间item的左、右divider看上去稍微好看些,实际开发中,如果要处理,那么恢复 drawHorizontal方法中的2注释(还要注释掉1注释)以及 drawVertical方法中的4注释(还要注释掉3注释),可详见demo

嗯,以上就是主要的修改代码,下面附上demo下载链接,点我下载~

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android RecyclerView 使用完全解析 体验艺术般的控件

Android RecyclerView 使用完全解析 概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。 据官方的介绍...
  • lmj623565791
  • lmj623565791
  • 2015年04月16日 09:07
  • 839253

使用DividerGridItemDecoration遇到的坑

使用很简单 mRecyclerView.addItemDecoration(new DividerGridItemDecoration(getActivity())); 就搞定了。 可是我在st...
  • zx_android
  • zx_android
  • 2016年05月12日 14:04
  • 1479

Android-UI布局---RecyclerView学习(四)匹配GridLayoutManager的ItemDecoration

该系列文章  如果想全方面学习,建议参考这个大牛的文章,写的真可以。 地址:http://blog.csdn.net/lmj623565791/article/details/45059587 ...
  • u014737138
  • u014737138
  • 2015年11月16日 21:44
  • 7294

AndroidRecyclerviewGridLayoutManager列间距 - Android Recyclerview GridLayoutManager column spacing

解决方案: RecyclerViews支持ItemDecoration的概念:特殊补偿和绘画在每个元素。见这个答案,您可以使用然后通过添加 原文: RecyclerViews support...
  • yanggz888
  • yanggz888
  • 2017年01月12日 16:27
  • 13500

Android中RecycleView使用GridLayoutManager时自适应高度

recyclerView.setLayoutManager(new GridLayoutManager(activity, 3) { @Over...
  • s562218
  • s562218
  • 2015年11月09日 21:07
  • 5969

RecyclerView在GridLayoutManager情况下实现四周都有分割线的ItemDecoration

感谢:http://www.jianshu.com/p/d58cbd61c40a _SOLID 之前UI有个比较特别的需求,一个gridview形式的列表,但是四周都有白色的分割线: 类似这个效...
  • qq_21731063
  • qq_21731063
  • 2017年05月19日 14:58
  • 3940

RecyclerView 边框线设置

本人新手,写这个博客主要给自己看,有什么错误的地方 ,还望指正,不喜勿喷。 import android.graphics.Canvas; import android.graphics.Paint...
  • god_sunht
  • god_sunht
  • 2016年10月13日 15:39
  • 2098

Android中RecyclerView设置边框并循环滚动

编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/689398091,Demo展示图片: 2,布局代码如...
  • zxc514257857
  • zxc514257857
  • 2017年04月01日 00:41
  • 2247

RecyclerView GridLayoutManager 设置分割线 万能分割

万能的分割线,如有另需请自行修改 上效果图 下面是源码 package com.qianfandu.adapter; import android.graphics.Canvas; impor...
  • u010523832
  • u010523832
  • 2016年11月04日 09:27
  • 7349

RecyclerView中利用GridLayoutManager实现item四周都带有分割线效果(更正版!!!)

  • 2016年12月02日 22:27
  • 22.78MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RecyclerView中利用GridLayoutManager实现item四周都带有分割线效果(更正版!!!)
举报原因:
原因补充:

(最多只允许输入30个字)