RecyclerView ItemDecoration 通用分割线

一个通用分割线,适用于GridView,当然也适用于普通的RecyclerView。
支持在item之间设置任何类型的间距,支持控制是否显示上下左右间隔及是否绘制上下左右背景

ItemDecoration

/**
 * Desc:适用于GridView,当然也适用于普通的RecyclerView
 * 支持在item之间设置任何类型的间距,支持控制是否显示上下左右间隔及是否绘制上下左右背景
 */
public class GridItemDecoration extends RecyclerView.ItemDecoration {
	
	private Drawable verticalDivider;
	private Drawable horizontalDivider;
	private int spanCount;
	private int verticalSpaceSize;
	private int horizontalSpaceSize;
	private boolean includeVerticalEdge;//是否绘制左右边界,注意不绘制并不表示没有预留边界空间
	private boolean includeHorizontalEdge;//是否绘制上下边界,注意不绘制并不表示没有预留边界空间
	
	private GridItemDecoration(Builder builder) {
		verticalDivider = builder.verticalDivider;
		horizontalDivider = builder.horizontalDivider;
		spanCount = builder.spanCount;
		verticalSpaceSize = builder.verticalSpaceSize;
		horizontalSpaceSize = builder.horizontalSpaceSize;
		includeVerticalEdge = builder.includeVerticalEdge;
		includeHorizontalEdge = builder.includeHorizontalEdge;
	}
	
	public static Builder newBuilder() {
		return new Builder();
	}
	
	@Override
	public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
		int position = parent.getChildAdapterPosition(view); // item position
		int column = position % spanCount; // item column
		if (verticalSpaceSize > 0) {
			outRect.left = verticalSpaceSize - column * verticalSpaceSize / spanCount;
			outRect.right = (column + 1) * verticalSpaceSize / spanCount;
		} else {
			outRect.left = column * verticalSpaceSize / spanCount;
			outRect.right = verticalSpaceSize - (column + 1) * verticalSpaceSize / spanCount;
		}
		
		if (horizontalSpaceSize > 0) {
			if (position < spanCount) outRect.top = horizontalSpaceSize; // top edge
			outRect.bottom = horizontalSpaceSize; // item bottom
		} else {
			if (position >= spanCount) outRect.top = horizontalSpaceSize; // item top
		}
		
		log("确定边界" + outRect.left + "  " + outRect.right + "  " + outRect.top + "  " + outRect.bottom);
	}
	
	@Override
	public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
		log(toString());
		//在边界上绘制图形
		if (horizontalDivider != null && horizontalSpaceSize > 0) {
			drawHorizontalLineAtItemTop(c, parent);//在每一个item的上面绘制水平分割线
			drawLineAtTopAndBottom(c, parent);//绘制上下边界,包括倒数第二行中的部分item
		}
		if (verticalDivider != null && verticalSpaceSize > 0) {
			drawVerticalLineAtItemLeft(c, parent);//绘制竖直分割线
			if (includeVerticalEdge) drawLR(c, parent);//绘制左右边界
		}
	}
	
	//在每一个item的上面绘制水平分割线
	private void drawHorizontalLineAtItemTop(Canvas c, RecyclerView parent) {
		int childCount = parent.getChildCount();
		for (int position = 0; position < childCount; position++) {
			if (position >= spanCount) {//第一行不绘制
				View child = parent.getChildAt(position);
				int left = child.getLeft();
				int right = (position % spanCount == spanCount - 1) ? child.getRight() : (child.getRight() + verticalSpaceSize);
				int top = child.getTop() - horizontalSpaceSize;
				int bottom = top + horizontalSpaceSize;
				log("绘制水平分割线" + left + "  " + right + "  " + top + "  " + bottom);
				horizontalDivider.setBounds(left, top, right, bottom);
				horizontalDivider.draw(c);
			}
		}
	}
	
	//绘制竖直分割线
	private void drawVerticalLineAtItemLeft(Canvas c, RecyclerView parent) {
		int childCount = parent.getChildCount();
		for (int position = 0; position < childCount; position++) {//第一列不绘制
			if (position % spanCount != 0) {
				View child = parent.getChildAt(position);
				int left = child.getLeft() - verticalSpaceSize;
				int right = left + verticalSpaceSize;
				int top = child.getTop() /*- horizontalSpaceSize*/;
				int bottom = child.getBottom();
				log("绘制竖直分割线" + left + "  " + right + "  " + top + "  " + bottom);
				verticalDivider.setBounds(left, top, right, bottom);
				verticalDivider.draw(c);
			}
		}
	}
	
	//绘制左右边界
	private void drawLR(Canvas c, RecyclerView parent) {
		int childCount = parent.getChildCount();
		for (int position = 0; position < childCount; position++) {
			View child = parent.getChildAt(position);
			
			int maxLines = (childCount % spanCount == 0) ? childCount / spanCount : (childCount / spanCount + 1);//一共有多少行
			boolean isLastLineItem = position / spanCount == maxLines - 1;//倒数第一行的元素
			//最左边那条线
			if (position % spanCount == 0) {
				int left = child.getLeft() - verticalSpaceSize;
				int right = left + verticalSpaceSize;
				int top = child.getTop() - horizontalSpaceSize;
				int bottom;
				if (isLastLineItem) {//【左下角】
					bottom = child.getBottom() + horizontalSpaceSize;
				} else {
					bottom = child.getBottom();
				}
				verticalDivider.setBounds(left, top, right, bottom);
				verticalDivider.draw(c);
				log("绘制最左边那条线" + left + "  " + right + "  " + top + "  " + bottom);
			}
			
			//最右边那条线
			if ((position + 1) % spanCount == 0) {
				int left = child.getRight();
				int right = left + verticalSpaceSize;
				int top = child.getTop() - horizontalSpaceSize;
				
				boolean isLastSecondLineItem = (position / spanCount == maxLines - 2) && (position + spanCount >= childCount);//倒数第二行的部分元素
				int bottom;
				if (isLastLineItem || isLastSecondLineItem) {
					bottom = child.getBottom() + horizontalSpaceSize;//【右下角】
				} else {
					bottom = child.getBottom();
				}
				verticalDivider.setBounds(left, top, right, bottom);
				verticalDivider.draw(c);
				log("绘制最右边那条线" + left + "  " + right + "  " + top + "  " + bottom);
			}
		}
	}
	
	//绘制上下边界,包括倒数第二行中的部分item
	private void drawLineAtTopAndBottom(Canvas c, RecyclerView parent) {
		int childCount = parent.getChildCount();
		for (int position = 0; position < childCount; position++) {
			View child = parent.getChildAt(position);
			
			//最上边那条线
			if (includeHorizontalEdge && position < spanCount) {
				int top = child.getTop() - horizontalSpaceSize;
				int bottom = top + horizontalSpaceSize;
				int left = child.getLeft();
				
				int right;
				boolean isRightEdgeItem = (position + 1) % spanCount == 0;//最右侧的元素
				boolean isFirstLineItem = childCount < spanCount && (position == childCount - 1);//只有一行的元素
				if (isRightEdgeItem || isFirstLineItem) {//【右上角】
					right = child.getRight();
				} else {
					right = child.getRight() + verticalSpaceSize;//如果同时有竖直分割线,则需要包含竖直分割线的宽度
				}
				
				horizontalDivider.setBounds(left, top, right, bottom);
				horizontalDivider.draw(c);
				log("绘制最上边那条线" + left + "  " + right + "  " + top + "  " + bottom);
			}
			
			//最下边那条线
			int maxLines = (childCount % spanCount == 0) ? childCount / spanCount : (childCount / spanCount + 1);//一共有多少行
			boolean isLastLineItem = position / spanCount == maxLines - 1;//倒数第一行的元素
			boolean isLastSecondLineItem = (position / spanCount == maxLines - 2) && (position + spanCount >= childCount);//倒数第二行的部分元素
			if ((includeHorizontalEdge && isLastLineItem) || isLastSecondLineItem) {
				int top = child.getBottom();
				int bottom = top + horizontalSpaceSize;
				int left = child.getLeft();
				int right;
				
				boolean isLastSecondLineEdgeItem = isLastSecondLineItem && ((position + 1) % spanCount == 0);//倒数第二行最后一个元素
				if (position == childCount - 1 || isLastSecondLineEdgeItem) {//【右下角】
					right = child.getRight();
				} else {
					right = child.getRight() + verticalSpaceSize;//如果同时有竖直分割线,则需要包含竖直分割线的宽度
				}
				
				horizontalDivider.setBounds(left, top, right, bottom);
				horizontalDivider.draw(c);
				log("绘制最下边那条线" + left + "  " + right + "  " + top + "  " + bottom);
			}
		}
	}
	
	public static final class Builder {
		private Drawable horizontalDivider;
		private Drawable verticalDivider;
		private int spanCount;
		private int horizontalSpaceSize;
		private int verticalSpaceSize;
		private boolean includeHorizontalEdge;
		private boolean includeVerticalEdge;
		
		private Builder() {
		}
		
		public Builder horizontalDivider(Drawable horizontalDivider, int horizontalSpaceSize, boolean includeHorizontalEdge) {
			this.horizontalDivider = horizontalDivider;
			this.horizontalSpaceSize = horizontalSpaceSize;
			this.includeHorizontalEdge = includeHorizontalEdge;
			return this;
		}
		
		public Builder verticalDivider(Drawable verticalDivider, int verticalSpaceSize, boolean includeVerticalEdge) {
			this.verticalDivider = verticalDivider;
			this.verticalSpaceSize = verticalSpaceSize;
			this.includeVerticalEdge = includeVerticalEdge;
			return this;
		}
		
		public Builder spanCount(int val) {
			spanCount = val;
			return this;
		}
		
		public GridItemDecoration build() {
			return new GridItemDecoration(this);
		}
	}
	
	private void log(String msg) {
		Log.i("bqt", "【】" + msg);
	}

}
x
1
/**
2
 * Desc:适用于GridView,当然也适用于普通的RecyclerView
3
 * 支持在item之间设置任何类型的间距,支持控制是否显示上下左右间隔及是否绘制上下左右背景
4
 */
5
public class GridItemDecoration extends RecyclerView.ItemDecoration {
6
    
7
    private Drawable verticalDivider;
8
    private Drawable horizontalDivider;
9
    private int spanCount;
10
    private int verticalSpaceSize;
11
    private int horizontalSpaceSize;
12
    private boolean includeVerticalEdge;//是否绘制左右边界,注意不绘制并不表示没有预留边界空间
13
    private boolean includeHorizontalEdge;//是否绘制上下边界,注意不绘制并不表示没有预留边界空间
14
    
15
    private GridItemDecoration(Builder builder) {
16
        verticalDivider = builder.verticalDivider;
17
        horizontalDivider = builder.horizontalDivider;
18
        spanCount = builder.spanCount;
19
        verticalSpaceSize = builder.verticalSpaceSize;
20
        horizontalSpaceSize = builder.horizontalSpaceSize;
21
        includeVerticalEdge = builder.includeVerticalEdge;
22
        includeHorizontalEdge = builder.includeHorizontalEdge;
23
    }
24
    
25
    public static Builder newBuilder() {
26
        return new Builder();
27
    }
28
    
29
    @Override
30
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
31
        int position = parent.getChildAdapterPosition(view); // item position
32
        int column = position % spanCount; // item column
33
        if (verticalSpaceSize > 0) {
34
            outRect.left = verticalSpaceSize - column * verticalSpaceSize / spanCount;
35
            outRect.right = (column + 1) * verticalSpaceSize / spanCount;
36
        } else {
37
            outRect.left = column * verticalSpaceSize / spanCount;
38
            outRect.right = verticalSpaceSize - (column + 1) * verticalSpaceSize / spanCount;
39
        }
40
        
41
        if (horizontalSpaceSize > 0) {
42
            if (position < spanCount) outRect.top = horizontalSpaceSize; // top edge
43
            outRect.bottom = horizontalSpaceSize; // item bottom
44
        } else {
45
            if (position >= spanCount) outRect.top = horizontalSpaceSize; // item top
46
        }
47
        
48
        log("确定边界" + outRect.left + "  " + outRect.right + "  " + outRect.top + "  " + outRect.bottom);
49
    }
50
    
51
    @Override
52
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
53
        log(toString());
54
        //在边界上绘制图形
55
        if (horizontalDivider != null && horizontalSpaceSize > 0) {
56
            drawHorizontalLineAtItemTop(c, parent);//在每一个item的上面绘制水平分割线
57
            drawLineAtTopAndBottom(c, parent);//绘制上下边界,包括倒数第二行中的部分item
58
        }
59
        if (verticalDivider != null && verticalSpaceSize > 0) {
60
            drawVerticalLineAtItemLeft(c, parent);//绘制竖直分割线
61
            if (includeVerticalEdge) drawLR(c, parent);//绘制左右边界
62
        }
63
    }
64
    
65
    //在每一个item的上面绘制水平分割线
66
    private void drawHorizontalLineAtItemTop(Canvas c, RecyclerView parent) {
67
        int childCount = parent.getChildCount();
68
        for (int position = 0; position < childCount; position++) {
69
            if (position >= spanCount) {//第一行不绘制
70
                View child = parent.getChildAt(position);
71
                int left = child.getLeft();
72
                int right = (position % spanCount == spanCount - 1) ? child.getRight() : (child.getRight() + verticalSpaceSize);
73
                int top = child.getTop() - horizontalSpaceSize;
74
                int bottom = top + horizontalSpaceSize;
75
                log("绘制水平分割线" + left + "  " + right + "  " + top + "  " + bottom);
76
                horizontalDivider.setBounds(left, top, right, bottom);
77
                horizontalDivider.draw(c);
78
            }
79
        }
80
    }
81
    
82
    //绘制竖直分割线
83
    private void drawVerticalLineAtItemLeft(Canvas c, RecyclerView parent) {
84
        int childCount = parent.getChildCount();
85
        for (int position = 0; position < childCount; position++) {//第一列不绘制
86
            if (position % spanCount != 0) {
87
                View child = parent.getChildAt(position);
88
                int left = child.getLeft() - verticalSpaceSize;
89
                int right = left + verticalSpaceSize;
90
                int top = child.getTop() /*- horizontalSpaceSize*/;
91
                int bottom = child.getBottom();
92
                log("绘制竖直分割线" + left + "  " + right + "  " + top + "  " + bottom);
93
                verticalDivider.setBounds(left, top, right, bottom);
94
                verticalDivider.draw(c);
95
            }
96
        }
97
    }
98
    
99
    //绘制左右边界
100
    private void drawLR(Canvas c, RecyclerView parent) {
101
        int childCount = parent.getChildCount();
102
        for (int position = 0; position < childCount; position++) {
103
            View child = parent.getChildAt(position);
104
            
105
            int maxLines = (childCount % spanCount == 0) ? childCount / spanCount : (childCount / spanCount + 1);//一共有多少行
106
            boolean isLastLineItem = position / spanCount == maxLines - 1;//倒数第一行的元素
107
            //最左边那条线
108
            if (position % spanCount == 0) {
109
                int left = child.getLeft() - verticalSpaceSize;
110
                int right = left + verticalSpaceSize;
111
                int top = child.getTop() - horizontalSpaceSize;
112
                int bottom;
113
                if (isLastLineItem) {//【左下角】
114
                    bottom = child.getBottom() + horizontalSpaceSize;
115
                } else {
116
                    bottom = child.getBottom();
117
                }
118
                verticalDivider.setBounds(left, top, right, bottom);
119
                verticalDivider.draw(c);
120
                log("绘制最左边那条线" + left + "  " + right + "  " + top + "  " + bottom);
121
            }
122
            
123
            //最右边那条线
124
            if ((position + 1) % spanCount == 0) {
125
                int left = child.getRight();
126
                int right = left + verticalSpaceSize;
127
                int top = child.getTop() - horizontalSpaceSize;
128
                
129
                boolean isLastSecondLineItem = (position / spanCount == maxLines - 2) && (position + spanCount >= childCount);//倒数第二行的部分元素
130
                int bottom;
131
                if (isLastLineItem || isLastSecondLineItem) {
132
                    bottom = child.getBottom() + horizontalSpaceSize;//【右下角】
133
                } else {
134
                    bottom = child.getBottom();
135
                }
136
                verticalDivider.setBounds(left, top, right, bottom);
137
                verticalDivider.draw(c);
138
                log("绘制最右边那条线" + left + "  " + right + "  " + top + "  " + bottom);
139
            }
140
        }
141
    }
142
    
143
    //绘制上下边界,包括倒数第二行中的部分item
144
    private void drawLineAtTopAndBottom(Canvas c, RecyclerView parent) {
145
        int childCount = parent.getChildCount();
146
        for (int position = 0; position < childCount; position++) {
147
            View child = parent.getChildAt(position);
148
            
149
            //最上边那条线
150
            if (includeHorizontalEdge && position < spanCount) {
151
                int top = child.getTop() - horizontalSpaceSize;
152
                int bottom = top + horizontalSpaceSize;
153
                int left = child.getLeft();
154
                
155
                int right;
156
                boolean isRightEdgeItem = (position + 1) % spanCount == 0;//最右侧的元素
157
                boolean isFirstLineItem = childCount < spanCount && (position == childCount - 1);//只有一行的元素
158
                if (isRightEdgeItem || isFirstLineItem) {//【右上角】
159
                    right = child.getRight();
160
                } else {
161
                    right = child.getRight() + verticalSpaceSize;//如果同时有竖直分割线,则需要包含竖直分割线的宽度
162
                }
163
                
164
                horizontalDivider.setBounds(left, top, right, bottom);
165
                horizontalDivider.draw(c);
166
                log("绘制最上边那条线" + left + "  " + right + "  " + top + "  " + bottom);
167
            }
168
            
169
            //最下边那条线
170
            int maxLines = (childCount % spanCount == 0) ? childCount / spanCount : (childCount / spanCount + 1);//一共有多少行
171
            boolean isLastLineItem = position / spanCount == maxLines - 1;//倒数第一行的元素
172
            boolean isLastSecondLineItem = (position / spanCount == maxLines - 2) && (position + spanCount >= childCount);//倒数第二行的部分元素
173
            if ((includeHorizontalEdge && isLastLineItem) || isLastSecondLineItem) {
174
                int top = child.getBottom();
175
                int bottom = top + horizontalSpaceSize;
176
                int left = child.getLeft();
177
                int right;
178
                
179
                boolean isLastSecondLineEdgeItem = isLastSecondLineItem && ((position + 1) % spanCount == 0);//倒数第二行最后一个元素
180
                if (position == childCount - 1 || isLastSecondLineEdgeItem) {//【右下角】
181
                    right = child.getRight();
182
                } else {
183
                    right = child.getRight() + verticalSpaceSize;//如果同时有竖直分割线,则需要包含竖直分割线的宽度
184
                }
185
                
186
                horizontalDivider.setBounds(left, top, right, bottom);
187
                horizontalDivider.draw(c);
188
                log("绘制最下边那条线" + left + "  " + right + "  " + top + "  " + bottom);
189
            }
190
        }
191
    }
192
    
193
    public static final class Builder {
194
        private Drawable horizontalDivider;
195
        private Drawable verticalDivider;
196
        private int spanCount;
197
        private int horizontalSpaceSize;
198
        private int verticalSpaceSize;
199
        private boolean includeHorizontalEdge;
200
        private boolean includeVerticalEdge;
201
        
202
        private Builder() {
203
        }
204
        
205
        public Builder horizontalDivider(Drawable horizontalDivider, int horizontalSpaceSize, boolean includeHorizontalEdge) {
206
            this.horizontalDivider = horizontalDivider;
207
            this.horizontalSpaceSize = horizontalSpaceSize;
208
            this.includeHorizontalEdge = includeHorizontalEdge;
209
            return this;
210
        }
211
        
212
        public Builder verticalDivider(Drawable verticalDivider, int verticalSpaceSize, boolean includeVerticalEdge) {
213
            this.verticalDivider = verticalDivider;
214
            this.verticalSpaceSize = verticalSpaceSize;
215
            this.includeVerticalEdge = includeVerticalEdge;
216
            return this;
217
        }
218
        
219
        public Builder spanCount(int val) {
220
            spanCount = val;
221
            return this;
222
        }
223
        
224
        public GridItemDecoration build() {
225
            return new GridItemDecoration(this);
226
        }
227
    }
228
    
229
    private void log(String msg) {
230
        Log.i("bqt", "【】" + msg);
231
    }
232
233
}

测试代码

public class MainActivity extends Activity implements RecyclerAdapter.MyOnItemClickLitener {
	private RecyclerView mRecyclerView;
	private int spanCount;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		String[] array = {"0、水平分割线,包含上下边界",
				"1、水平分割线,不包含上下边界",
				"2、竖直分割线,包含左右边界",
				"3、竖直分割线,不包含左右边界",
				
				"4、水平分割线+透明竖直分割线,包含边界",
				"5、水平分割线+透明竖直分割线,不包含边界",
				"6、透明水平分割线+竖直分割线,包含边界",
				"7、透明水平分割线+竖直分割线,不包含边界",
				
				"8、【水平分割线+竖直分割线,包含边界】",
				"9、【水平分割线+竖直分割线,不包含边界】",
				"10、图片分割线+竖直分割线,包含边界",
				"11、图片分割线+竖直分割线,不包含边界",
				
				"12、重置",
				"13、重置",
				"14、重置",};
		spanCount = 1 + new Random().nextInt(5);
		RecyclerAdapter mRecyclerViewAdapter = new RecyclerAdapter(this, Arrays.asList(array));
		mRecyclerViewAdapter.setOnItemClickLitener(this);
		
		mRecyclerView = new RecyclerView(this);
		mRecyclerView.setBackgroundColor(Color.BLACK);
		mRecyclerView.setAdapter(mRecyclerViewAdapter);//设置adapter
		mRecyclerView.setLayoutManager(new GridLayoutManager(this, spanCount));//设置布局管理器
		mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置Item增加、移除动画
		setContentView(mRecyclerView);
	}
	
	@Override
	public void onItemClick(View view, int position) {
		GridItemDecoration decoration = null;
		switch (position) {
			case 0:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(0x88ff0000), 60, true)
						.build();
				break;
			case 1:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(0x88ff0000), 60, false)
						.build();
				break;
			case 2:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
						.build();
				break;
			case 3:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
						.build();
				break;
			//******************************************************************************************
			case 4:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(0x88ff0000), 20, true)
						.verticalDivider(new ColorDrawable(Color.TRANSPARENT), 60, true)
						.build();
				break;
			case 5:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(0x88ff0000), 20, false)
						.verticalDivider(new ColorDrawable(Color.TRANSPARENT), 60, false)
						.build();
				break;
			case 6:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(Color.TRANSPARENT), 20, true)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
						.build();
				break;
			case 7:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(Color.TRANSPARENT), 20, false)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
						.build();
				break;
			//******************************************************************************************
			case 8:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(0x88ff0000), 20, true)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
						.build();
				break;
			case 9:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(new ColorDrawable(0x88ff0000), 20, false)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
						.build();
				break;
			case 10:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(getResources().getDrawable(R.drawable.icon2), 20, true)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
						.build();
				break;
			case 11:
				decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
						.horizontalDivider(getResources().getDrawable(R.drawable.icon2), 20, false)
						.verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
						.build();
				break;
			case 12:
			case 13:
			case 14:
				recreate();
				return;
		}
		mRecyclerView.addItemDecoration(decoration);
	}
	
	@Override
	public void onItemLongClick(View view, int position) {
	    recreate();
	}
}
124
 
1
public class MainActivity extends Activity implements RecyclerAdapter.MyOnItemClickLitener {
2
    private RecyclerView mRecyclerView;
3
    private int spanCount;
4
    
5
    protected void onCreate(Bundle savedInstanceState) {
6
        super.onCreate(savedInstanceState);
7
        String[] array = {"0、水平分割线,包含上下边界",
8
                "1、水平分割线,不包含上下边界",
9
                "2、竖直分割线,包含左右边界",
10
                "3、竖直分割线,不包含左右边界",
11
                
12
                "4、水平分割线+透明竖直分割线,包含边界",
13
                "5、水平分割线+透明竖直分割线,不包含边界",
14
                "6、透明水平分割线+竖直分割线,包含边界",
15
                "7、透明水平分割线+竖直分割线,不包含边界",
16
                
17
                "8、【水平分割线+竖直分割线,包含边界】",
18
                "9、【水平分割线+竖直分割线,不包含边界】",
19
                "10、图片分割线+竖直分割线,包含边界",
20
                "11、图片分割线+竖直分割线,不包含边界",
21
                
22
                "12、重置",
23
                "13、重置",
24
                "14、重置",};
25
        spanCount = 1 + new Random().nextInt(5);
26
        RecyclerAdapter mRecyclerViewAdapter = new RecyclerAdapter(this, Arrays.asList(array));
27
        mRecyclerViewAdapter.setOnItemClickLitener(this);
28
        
29
        mRecyclerView = new RecyclerView(this);
30
        mRecyclerView.setBackgroundColor(Color.BLACK);
31
        mRecyclerView.setAdapter(mRecyclerViewAdapter);//设置adapter
32
        mRecyclerView.setLayoutManager(new GridLayoutManager(this, spanCount));//设置布局管理器
33
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置Item增加、移除动画
34
        setContentView(mRecyclerView);
35
    }
36
    
37
    @Override
38
    public void onItemClick(View view, int position) {
39
        GridItemDecoration decoration = null;
40
        switch (position) {
41
            case 0:
42
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
43
                        .horizontalDivider(new ColorDrawable(0x88ff0000), 60, true)
44
                        .build();
45
                break;
46
            case 1:
47
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
48
                        .horizontalDivider(new ColorDrawable(0x88ff0000), 60, false)
49
                        .build();
50
                break;
51
            case 2:
52
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
53
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
54
                        .build();
55
                break;
56
            case 3:
57
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
58
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
59
                        .build();
60
                break;
61
            //******************************************************************************************
62
            case 4:
63
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
64
                        .horizontalDivider(new ColorDrawable(0x88ff0000), 20, true)
65
                        .verticalDivider(new ColorDrawable(Color.TRANSPARENT), 60, true)
66
                        .build();
67
                break;
68
            case 5:
69
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
70
                        .horizontalDivider(new ColorDrawable(0x88ff0000), 20, false)
71
                        .verticalDivider(new ColorDrawable(Color.TRANSPARENT), 60, false)
72
                        .build();
73
                break;
74
            case 6:
75
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
76
                        .horizontalDivider(new ColorDrawable(Color.TRANSPARENT), 20, true)
77
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
78
                        .build();
79
                break;
80
            case 7:
81
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
82
                        .horizontalDivider(new ColorDrawable(Color.TRANSPARENT), 20, false)
83
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
84
                        .build();
85
                break;
86
            //******************************************************************************************
87
            case 8:
88
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
89
                        .horizontalDivider(new ColorDrawable(0x88ff0000), 20, true)
90
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
91
                        .build();
92
                break;
93
            case 9:
94
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
95
                        .horizontalDivider(new ColorDrawable(0x88ff0000), 20, false)
96
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
97
                        .build();
98
                break;
99
            case 10:
100
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
101
                        .horizontalDivider(getResources().getDrawable(R.drawable.icon2), 20, true)
102
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, true)
103
                        .build();
104
                break;
105
            case 11:
106
                decoration = GridItemDecoration.newBuilder().spanCount(spanCount)
107
                        .horizontalDivider(getResources().getDrawable(R.drawable.icon2), 20, false)
108
                        .verticalDivider(new ColorDrawable(0x88ff0000), 60, false)
109
                        .build();
110
                break;
111
            case 12:
112
            case 13:
113
            case 14:
114
                recreate();
115
                return;
116
        }
117
        mRecyclerView.addItemDecoration(decoration);
118
    }
119
    
120
    @Override
121
    public void onItemLongClick(View view, int position) {
122
        recreate();
123
    }
124
}

Adapter

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
	private Context context;
	private List<String> mDatas;
	private MyOnItemClickLitener mOnItemClickLitener;
	
	public RecyclerAdapter(Context context, List<String> mDatas) {
		this.context = context;
		this.mDatas = mDatas;
	}
	
	@NonNull
	@Override
	public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
		return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
	}
	
	@Override
	public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
		holder.tv.setText(mDatas.get(position));
		
		// 如果设置了回调,则设置点击事件
		holder.itemView.setOnClickListener(v -> {
			if (mOnItemClickLitener != null) mOnItemClickLitener.onItemClick(holder.itemView, holder.getAdapterPosition());
		});
		holder.itemView.setOnLongClickListener(v -> {
			if (mOnItemClickLitener != null) mOnItemClickLitener.onItemLongClick(holder.itemView, holder.getAdapterPosition());
			return false;
		});
	}
	
	@Override
	public int getItemCount() {
		return mDatas.size();
	}
	
	/**
	 * 添加并更新数据,同时具有动画效果
	 */
	public void addDataAt(int position, String data) {
		mDatas.add(position, data);
		notifyItemInserted(position);//更新数据集,注意如果用adapter.notifyDataSetChanged()将没有动画效果
	}
	
	/**
	 * 移除并更新数据,同时具有动画效果
	 */
	public void removeDataAt(int position) {
		mDatas.remove(position);
		notifyItemRemoved(position);
	}
	
	public void setOnItemClickLitener(MyOnItemClickLitener mOnItemClickLitener) {
		this.mOnItemClickLitener = mOnItemClickLitener;
	}
	
	class MyViewHolder extends RecyclerView.ViewHolder {
		TextView tv;
		
		public MyViewHolder(View view) {
			super(view);
			tv = view.findViewById(R.id.tv_name);
		}
	}
	
	public interface MyOnItemClickLitener {
		void onItemClick(View view, int position);
		
		void onItemLongClick(View view, int position);
	}
}
x
 
1
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
2
    private Context context;
3
    private List<String> mDatas;
4
    private MyOnItemClickLitener mOnItemClickLitener;
5
    
6
    public RecyclerAdapter(Context context, List<String> mDatas) {
7
        this.context = context;
8
        this.mDatas = mDatas;
9
    }
10
    
11
    @NonNull
12
    @Override
13
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
14
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
15
    }
16
    
17
    @Override
18
    public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
19
        holder.tv.setText(mDatas.get(position));
20
        
21
        // 如果设置了回调,则设置点击事件
22
        holder.itemView.setOnClickListener(v -> {
23
            if (mOnItemClickLitener != null) mOnItemClickLitener.onItemClick(holder.itemView, holder.getAdapterPosition());
24
        });
25
        holder.itemView.setOnLongClickListener(v -> {
26
            if (mOnItemClickLitener != null) mOnItemClickLitener.onItemLongClick(holder.itemView, holder.getAdapterPosition());
27
            return false;
28
        });
29
    }
30
    
31
    @Override
32
    public int getItemCount() {
33
        return mDatas.size();
34
    }
35
    
36
    /**
37
     * 添加并更新数据,同时具有动画效果
38
     */
39
    public void addDataAt(int position, String data) {
40
        mDatas.add(position, data);
41
        notifyItemInserted(position);//更新数据集,注意如果用adapter.notifyDataSetChanged()将没有动画效果
42
    }
43
    
44
    /**
45
     * 移除并更新数据,同时具有动画效果
46
     */
47
    public void removeDataAt(int position) {
48
        mDatas.remove(position);
49
        notifyItemRemoved(position);
50
    }
51
    
52
    public void setOnItemClickLitener(MyOnItemClickLitener mOnItemClickLitener) {
53
        this.mOnItemClickLitener = mOnItemClickLitener;
54
    }
55
    
56
    class MyViewHolder extends RecyclerView.ViewHolder {
57
        TextView tv;
58
        
59
        public MyViewHolder(View view) {
60
            super(view);
61
            tv = view.findViewById(R.id.tv_name);
62
        }
63
    }
64
    
65
    public interface MyOnItemClickLitener {
66
        void onItemClick(View view, int position);
67
        
68
        void onItemLongClick(View view, int position);
69
    }
70
}

item

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_name"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:background="#00f"
    android:gravity="center"
    android:text="包青天"
    android:textColor="#fff"
    android:textSize="12sp"/>
11
1
<?xml version="1.0" encoding="utf-8"?>
2
<TextView
3
    xmlns:android="http://schemas.android.com/apk/res/android"
4
    android:id="@+id/tv_name"
5
    android:layout_width="match_parent"
6
    android:layout_height="80dp"
7
    android:background="#00f"
8
    android:gravity="center"
9
    android:text="包青天"
10
    android:textColor="#fff"
11
    android:textSize="12sp"/>
2018-5-18




猜你喜欢

转载自www.cnblogs.com/baiqiantao/p/19762fb101659e8f4c1cea53e7acb446.html