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

来源:互联网 发布:python正则表达式大全 编辑:程序博客网 时间:2024/05/16 17:41

强大的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
预览效果

任何都不配置,就画1px的灰色水平线,不包含头尾
这里写图片描述

1 0
原创粉丝点击