强大的RecyclerView,从他的源码中发现好像只可以配置一个属性layoutManager,例如
app:layoutManager="GridLayoutManager"
有了这个我们不用在代码中控制布局方向横向ListView,还是竖向ListView,还是GridView了
配置了GridLayoutManager这个属性,我们翻翻他的源码,找到这个方法:
public static Properties getProperties(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
Properties properties = new Properties();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,
defStyleAttr, defStyleRes);
properties.orientation = a.getInt(R.styleable.RecyclerView_android_orientation, VERTICAL);
properties.spanCount = a.getInt(R.styleable.RecyclerView_spanCount, 1);
properties.reverseLayout = a.getBoolean(R.styleable.RecyclerView_reverseLayout, false);
properties.stackFromEnd = a.getBoolean(R.styleable.RecyclerView_stackFromEnd, false);
a.recycle();
return properties;
}
发现在GridLayoutManager下还能配置
android_orientation 表示布局方向,是横向拖动还是竖向拖动
spanCount 每行或每列的个数,,相当于GridView的numColum
reverseLayout 从后面往前面开始堆放item
stackFromEnd error
LinearLayoutManager能配置的,源码居然一样
android_orientation 方向
stackFromEnd 如果数据摆不完则在前面留空
reverseLayout 从后面往前面开始堆放item
spanCount 无效
可以组合一些不常用的效果.不用在代码里面去实现,易修改和预览效果
RecyclerView的分割线绘制是一个问题,想了一个办法去实现在xml中随意配置分割线,目前只支持绘制颜色
attrs.xml文件中增加.配置的属性如下
<declare-styleable name="divder">
<attr name="_drawBound" format="boolean" />
<attr name="_thickness" format="dimension" />
<attr name="_dividerPadding" format="dimension" />
<attr name="_dividerColor" format="color" />
<attr name="_orientation" format="enum">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
<enum name="grid" value="2" />
attr>
<attr name="_grid_col_num" format="integer" />
declare-styleable>
_drawBound———是否画边界,作用于list时表示是否画头和尾
_thickness————分割线的粗细
_dividerPadding—-分割线两端留白
_dividerColor——–颜色
_orientation ———方向,为grid则会横竖都画
实现一个从xml文件中读取分割线配置方式的类
public class DividerLine extends RecyclerView.ItemDecoration {
private int mColor = Color.GRAY;
private int thickness = DEFAULT_THICKNESS;
private int padding;
private static final int DEFAULT_THICKNESS = 1;
private int orientation = HORIZONTAL;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int GRID = 2;
private boolean drawBound = false;
private int gridNum = 1;
public DividerLine(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.divder);
mColor = a.getColor(R.styleable.divder__dividerColor, mColor);
padding = (int) a.getDimension(R.styleable.divder__dividerPadding, padding);
thickness = (int) a.getDimension(R.styleable.divder__thickness, thickness);
orientation = a.getInt(R.styleable.divder__orientation, 0);
drawBound = a.getBoolean(R.styleable.divder__drawBound, false);
gridNum = a.getInt(R.styleable.divder__grid_col_num, 1);
a.recycle();
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent) {
Paint p = new Paint();
p.setColor(mColor);
p.setStrokeWidth(thickness);
//画最前面的一个头部分割线
if (drawBound && parent.getChildCount() > 0) {
View v = parent.getChildAt(0);
if (orientation == HORIZONTAL) {
//画水平位置的分隔线
c.drawLine(v.getLeft() + padding, v.getTop(), v.getRight() - padding, v.getTop(), p);
}
if (orientation == VERTICAL) {
//画竖直位置的分隔线(GridView)
c.drawLine(v.getLeft(), v.getTop()+ padding, v.getLeft(), v.getBottom() - padding, p);
}
if (orientation == GRID) {
for (int i = 0; i < parent.getChildCount(); i += gridNum) {
v= parent.getChildAt(i);
//都画
c.drawLine(v.getLeft() + padding, v.getTop(), v.getRight() - padding, v.getTop(), p);
c.drawLine(v.getLeft(), v.getTop()+ padding, v.getLeft(), v.getBottom() - padding, p);
}
}
}
int to = drawBound ? parent.getChildCount() : parent.getChildCount() - 1;
for (int i = 0; i < to; i++) {
View v = parent.getChildAt(i);
if (orientation == 0) {
//画水平位置的分隔线
c.drawLine(v.getLeft() + padding, v.getBottom(), v.getRight() - padding, v.getBottom(), p);
//画竖直位置的分隔线(GridView)
}
if (orientation == 1) {
c.drawLine(v.getRight(), v.getTop()+ padding, v.getRight(), v.getBottom()- padding, p);
}
if (orientation == GRID) {
c.drawLine(v.getLeft() + padding, v.getBottom(), v.getRight() - padding, v.getBottom(), p);
c.drawLine(v.getRight(), v.getTop()+ padding, v.getRight(), v.getBottom()- padding, p);
}
}
}
}
继承RecyclerView
需要自定义View,主动实现添加分割线的方法
public class MyRecyclerView extends RecyclerView{
public MyRecyclerView(Context context) {
super(context);
}
public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
addItemDecoration(new DividerLine(context,attrs));
}
}
在xml中配置用法
<com.xxxxx.MyRecyclerView
android:id="@+id/rv_home_news"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/_18dp"
android:background="@color/background"
android:padding="@dimen/_8dp"
app:layoutManager="GridLayoutManager"
app:spanCount="3"
divider:_dividerColor="@color/dialog_red"
divider:_drawBound="true"
divider:_dividerPadding="@dimen/_0dp"
divider:_orientation="grid"
divider:_thickness="1px">
com.xxxxx.MyRecyclerView>