自定义GridView实现分割线解析

前两天在些项目的时候碰到常用的GridView要实现一些分割线,之前就是用本方法利用listView和Item的背景颜色的不同线显示分割线。这是最low的一种做法。于是我就简单的写了一个自定义的 GridView。

我们可以先看List怎么设置分割线
android:divider
android:dividerHeight
  • 1
  • 2
  • 1
  • 2

然而我们都知道 GirdView默认是没有网格线的,那么该如何设置呢?

如何设置GridView的分割线

  • 第一种通过设置背景颜色的不同来充当divier 
    • 首先设置GridView的背景颜色
    • 设置item的背景颜色
    • 设置item的宽高
        <GridView
            android:id="@+id/mgv_griview2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:background="@color/black3"
            android:horizontalSpacing="1dp"
            android:verticalSpacing="1dp"
            android:padding="2dp"
            android:numColumns="3" >
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:gravity="center"
    android:layout_margin="5dp" 
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@drawable/ic_launcher"
        android:id="@+id/myitem_gv"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_marginTop="10dp"
        android:text="图片"/>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

自定义View来解决GridView的分割线

效果图 
Markdown

**
 *  类功能描述:</br>
 * Created by Administrator on 2017/2/19 0018.
 * 博客地址: http://blog.csdn.net/androidstarjack
 * @author androidstar
 * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
 *  公众号: 终端研发部
 */

public class MyGridView extends GridView {
    /**
     * 默认的分割线的颜色
     * 也可以在布局中设置
     */
    private int diverColor = R.color.color1;
    /**
     * 默认的分割线的高度
     * 也可以在布局中设置
     */
    private int diverHeight = 1;
    /**
     * 所使用的画笔
     */
    private Paint paint;

    private  Context context;
    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context =context;
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.gv_acusttrs);
        diverHeight = (int) typedArray.getDimension(R.styleable.gv_acusttrs_divierHeight,10);
        diverColor = typedArray.getResourceId(R.styleable.gv_acusttrs_divierColor,R.drawable.editext_slelect_black4);
        typedArray.recycle();
        paint = new Paint();
        paint.setColor(ContextCompat.getColor(context,diverColor));
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(diverHeight);
    }
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
    /**
     * 动态修改默认的分割线的颜色
     */
    public void setDiverColor(int diverColor){
        this.diverColor = diverColor;
        invalidate();
    }
    /**
     * 动态修改默认的分割线的颜色
     */
    public void setDiverHeight(int diverHeight){
        this.diverHeight = diverHeight;
        invalidate();
    }
    /**
     *
     * @param canvas
     */

  /*  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Rect rect = new Rect();
        rect.left = DensityUtil.getScreenIntWidth(context) / 4;
        rect.top = DensityUtil.getScreenIntHeight(context) / 4;
        rect.right = DensityUtil.getScreenIntWidth(context)/ 4 * 3;
        rect.bottom = DensityUtil.getScreenIntHeight(context)/ 4 * 3;
        canvas.drawRect(rect,paint);
    }*/
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        View localView1 = getChildAt(0);//得到第一个view
        int column = getWidth() / localView1.getWidth();//列数
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View cellView = getChildAt(i);
            if ((i + 1) % column == 0) {//每一行最后一个
                canvas.drawLine(cellView.getLeft(), cellView.getBottom(), cellView.getRight(), cellView.getBottom(), paint);
            } else if ((i + 1) > (childCount - (childCount % column))) {//最后一行的item
                canvas.drawLine(cellView.getRight(), cellView.getTop(), cellView.getRight(), cellView.getBottom(), paint);
            } else {
                canvas.drawLine(cellView.getRight(), cellView.getTop(), cellView.getRight(), cellView.getBottom(), paint);
                canvas.drawLine(cellView.getLeft(), cellView.getBottom(), cellView.getRight(), cellView.getBottom(), paint);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

我们都知道这里用到了dispatchDraw方法

/**
     * Called by draw to draw the child views. This may be overridden
     * by derived classes to gain control just before its children are drawn
     * (but after its own view has been drawn).
     * @param canvas the canvas on which to draw the view
     */
    protected void dispatchDraw(Canvas canvas) {

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • View组件的绘制会调用draw(Canvas canvas)方法,draw过程中主要是先画Drawable背景,对 drawable调用setBounds()然后是draw(Canvas c)方法.有点注意的是背景drawable的实际大小会影响view组件的大小,drawable的实际大小通过getIntrinsicWidth()和getIntrinsicHeight()获取,当背景比较大时view组件大小等于背景drawable的大小 
    画完背景后,draw过程会调用onDraw(Canvas canvas)方法,然后就是dispatchDraw(Canvas canvas)方法,
  • dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(),

相关demo现在地址: 
MyGridViewApplication.rar

posted @ 2017-06-15 17:45  请叫我码农怪蜀黍  阅读(1401)  评论(0编辑  收藏  举报