abfo12

过去不等于未来,用思考代替发问

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

今天,花了很长的时间才实现了如题的效果,回想一下,实现起来确实不难,只怪当时做的时候思路不清晰,没想好就动手了,这是病,得改!好了,不多说,实现工程中主要参考了鸿洋博客中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下载链接,点我下载~

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abfo12/article/details/51560112
文章标签: android
个人分类: android开发
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭