A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小鲁哥哥 于 2020-1-8 17:02 编辑



利用RecyclerView的ItemDecoration实现item间的蛇形连线。先上图大家看看效果:
原理很简单,就是重写ItemDecoration的getItemOffsets()方法设置item之间的边距,在onDraw()方法中根据item的位置来判断画横线还是竖线。

下面先来分析一下什么情况下画横向连接线,什么情况下画纵向连接线?
  • 画横向连接线
首先来分析一下横向连接线,在每一行中,只要当前的item不是最后一列就向右画一条横向的连接线。但是有个特例就是当前是最后一行,最后一个item不在最后一列,就要把这种特殊情况过滤出来否则就会出现下图这样的情况:

所以我们在onDraw()方法中画横向连接线有两个判断条件
[Java] 纯文本查看 复制代码
 if ((position % COLUMN_CONT != (COLUMN_CONT - 1)) && (position != mItems.size() - 1)) {
                        c.drawLine(childRight - mSpace, y, childRight + mSpace, y, mLinePaint);
                    }


  • 画纵向连接线
再来分析一下纵向连接线如何来画,情况好像比画横向连接线复杂了很多。分两种情况:
1.行的position是奇数时,第一列上的item向下画连接线,特殊情况就是当前是最后一行,如果不加以处理,就会出现下图的情况:

所以当前情况下的判断条件如下:
[AppleScript] 纯文本查看 复制代码
if (position % COLUMN_CONT == 0) {
                        //第一列中奇数行item与下一行第一个item连接,并且如果当前是最后一行也不画纵向连接线
                        if ((position / COLUMN_CONT) % 2 == 1 &&  position < mItems.size() - COLUMN_CONT) {
                            c.drawLine(x, childBotton - mSpace, x, childBotton + mSpace, mLinePaint);
                        }
                    }
                    



2.行的position是偶数时,最后一列上的item向下画连接线,这里面也有一种特殊情况,就是最后一行不能排满,如图:

处理方式要在最后一行前面补上空白item,将不能排满的item顶到后面去。也就说初始化数据时,如果最后一行不能排满并且position是奇数,就要在本行的前面加上空白item。
[AppleScript] 纯文本查看 复制代码
mItems.addAll(Arrays.asList(ITEMS));
                    temp.addAll(mItems.subList(0, ITEMS.length - (ITEMS.length) % COLUMN_CONT));
                    for (int i = 0; i < COLUMN_CONT - (ITEMS.length) % COLUMN_CONT; i++) {
                        temp.add("placeholder");
                    }
                    temp.addAll(mItems.subList(ITEMS.length - (ITEMS.length) % COLUMN_CONT, mItems.size()));
                    mItems = temp;

并且在onDraw()方法中要将添加的空白item过滤出来,否则:

正确显示效果如图:




  • 完整代码
[AppleScript] 纯文本查看 复制代码
package com.itheima.recyclerviewdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final int COLUMN_CONT = 6;
    private static final String[] ITEMS = {"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A"};
    private List<String> mItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, COLUMN_CONT, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerView.addItemDecoration(new ConnectorDecoration(this));
        recyclerView.setAdapter(new MyAdapter(this));
    }

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ItemHolder> {
        private LayoutInflater mLayoutInflater;
        private Context mContext;

        public MyAdapter(Context context) {
            mContext = context;
            mItems = new ArrayList<>();
            List<String> temp = new ArrayList<>();
            if (ITEMS.length % COLUMN_CONT == 0) {
                mItems.addAll(Arrays.asList(ITEMS));
            } else {
                if ((ITEMS.length / COLUMN_CONT) % 2 == 0) {
                    mItems.addAll(Arrays.asList(ITEMS));
                } else {
                    mItems.addAll(Arrays.asList(ITEMS));
                    temp.addAll(mItems.subList(0, ITEMS.length - (ITEMS.length) % COLUMN_CONT));
                    for (int i = 0; i < COLUMN_CONT - (ITEMS.length) % COLUMN_CONT; i++) {
                        temp.add("placeholder");
                    }
                    temp.addAll(mItems.subList(ITEMS.length - (ITEMS.length) % COLUMN_CONT, mItems.size()));
                    mItems = temp;
                }


            }
            mLayoutInflater = LayoutInflater.from(context);
        }

        @Override
        public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = mLayoutInflater.inflate(R.layout.item, parent, false);
            return new ItemHolder(view);
        }

        @Override
        public void onBindViewHolder(ItemHolder holder, int position) {
            if (mItems.get(position).equals("placeholder")) {
                holder.setText("");
                holder.tv.setBackgroundColor(Color.TRANSPARENT);
            } else {
                holder.tv.setBackgroundColor(mContext.getResources().getColor(R.color.colorLine));
                holder.setText(mItems.get(position));
            }

        }

        @Override
        public int getItemCount() {
            return mItems.size();
        }

        private ArrayList sortDatas(List<String> items) {
            ArrayList<String> tempItems = new ArrayList();
            int rowPostion = (items.size() - 1) / COLUMN_CONT;
            if ((items.size() - 1) % COLUMN_CONT != 0) {
                rowPostion = rowPostion + 1;
            }
            for (int i = 0; i < rowPostion - 1; i++) {
                if (i % 2 == 0) {
                    for (int j = 0; i < COLUMN_CONT - 1; j++) {

                        tempItems.add(items.get(i * COLUMN_CONT + j));
                    }
                } else {
                    for (int j = 0; i < COLUMN_CONT - 1; j++) {
                        if (i != rowPostion) {
                            tempItems.add(items.get((i + 1) * COLUMN_CONT - j));
                        }
                    }
                }
            }
            return tempItems;
        }

        public class ItemHolder extends RecyclerView.ViewHolder {
            private TextView tv;

            public ItemHolder(View itemView) {
                super(itemView);
                tv = (TextView) itemView.findViewById(R.id.item_tv);
            }

            public void setText(CharSequence text) {
                tv.setText(text);
            }
        }

    }

    public class ConnectorDecoration extends RecyclerView.ItemDecoration {
        private Paint mLinePaint;
        private int mSpace;

        public ConnectorDecoration(Context context) {
            super();
            mSpace = context.getResources().getDimensionPixelOffset(R.dimen.space_margin);
            int connectorWidth = context.getResources().getDimensionPixelOffset(R.dimen.connector_width);
            mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mLinePaint.setColor(context.getResources().getColor(R.color.colorLine));
            //设置连接线宽度
            mLinePaint.setStrokeWidth(connectorWidth);
        }

        /*
        设置每个item之间的边距
         */
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            outRect.set(mSpace, mSpace, mSpace, mSpace);
        }

        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            RecyclerView.LayoutManager manager = parent.getLayoutManager();
            for (int i = 0; i < parent.getChildCount(); i++) {
                View child = parent.getChildAt(i);
                int childLeft = manager.getDecoratedLeft(child);
                int childRight = manager.getDecoratedRight(child);
                int childTop = manager.getDecoratedTop(child);
                int childBotton = manager.getDecoratedBottom(child);
                //当前childview x轴方向的中间位置。
                int x = childLeft + ((childRight - childLeft) / 2);
                //当前childview y轴方向的中间位置。
                int y = childBotton + ((childTop - childBotton) / 2);
                int position = parent.getChildViewHolder(child).getLayoutPosition();
                if (!mItems.get(position).equals("placeholder")) {
                    //过滤出第一列上所有item的position
                    if (position % COLUMN_CONT == 0) {
                        //第一列中奇数行item与下一行第一个item连接,并且当前不是最后一个childview,并且如果当前是最后一行也不画纵向连接线
                        if ((position / COLUMN_CONT) % 2 == 1 && position < mItems.size() - COLUMN_CONT) {
                            c.drawLine(x, childBotton - mSpace, x, childBotton + mSpace, mLinePaint);
                        }
                        //过滤出最后一列上所有item的posiion
                    } else if (position % COLUMN_CONT == (COLUMN_CONT - 1)) {
                        //偶数行,最后一列向下画连接线,并且当前不是最后一个childview
                        if ((position / COLUMN_CONT) % 2 == 0 && (position != mItems.size() - 1)) {
                            c.drawLine(x, childBotton - mSpace, x, childBotton + mSpace, mLinePaint);
                        }
                    }
                    //当前childview不是每一行的最后一列,并且不是最后一个,画横向的连接线。
                    if ((position % COLUMN_CONT != (COLUMN_CONT - 1)) && (position != mItems.size() - 1)) {
                        c.drawLine(childRight - mSpace, y, childRight + mSpace, y, mLinePaint);
                    }
                }
            }
        }
    }
}






点评

xiexie  发表于 2016-8-7 21:13
我是来点赞的,棒棒哒  发表于 2016-8-2 22:48

评分

参与人数 1技术分 +10 黑马币 +10 收起 理由
济南王昭珽 + 10 + 10 好贴不断,尽在济南黑马程序员.

查看全部评分

31 个回复

倒序浏览
达文西叔叔 来自手机 初级黑马 2016-7-30 12:18:41
沙发
我是来点赞的
回复 使用道具 举报
前排酱油党!!!!!
回复 使用道具 举报
虽然看不懂,但好像很厉害的样子
回复 使用道具 举报
看不懂,还得继续学习,哈哈哈,加油吧,勿忘初心
回复 使用道具 举报
mark一下
回复 使用道具 举报
顶帖,日常顶帖
回复 使用道具 举报
蛇形连接,看起来好屌!
回复 使用道具 举报
看不懂,打酱油
回复 使用道具 举报
mengqishiye 来自手机 中级黑马 2016-8-2 01:33:24
10#
加油↖(^ω^)↗↖(^ω^)↗
回复 使用道具 举报
学什么都一样,努力就会有付出的!
回复 使用道具 举报
我也是来点赞的
回复 使用道具 举报
高手在民间
回复 使用道具 举报
我就是路过,不明觉厉
回复 使用道具 举报
23rssfgsfgssfsgssfgsgfs
回复 使用道具 举报
大神啊,膜拜
回复 使用道具 举报
表示真的看不懂啊!太高深了,还要继续努力
回复 使用道具 举报
赞。…。……。…。…。…。……
回复 使用道具 举报
表示看不懂
回复 使用道具 举报
写的真好
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马