RecyclerView可以在xml文件中配置的特别属性

强大的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>

这里可以实时观看预览效果
当然没有setAdapter,看不到实际item
RecyclerView可以在xml文件中配置的特别属性_第1张图片

任何都不配置,就画1px的灰色水平线,不包含头尾
RecyclerView可以在xml文件中配置的特别属性_第2张图片

你可能感兴趣的:(android,android,分割线,布局,xml,recycler)