自定義GridView實現分割線解析

前兩天在些項目的時候碰到經常使用的GridView要實現一些分割線,以前就是用本方法利用listView和Item的背景顏色的不一樣線顯示分割線。這是最low的一種作法。因而我就簡單的寫了一個自定義的 GridView。android

咱們能夠先看List怎麼設置分割線
android:divider
android:dividerHeight複製代碼

然而咱們都知道 GirdView默認是沒有網格線的,那麼該如何設置呢?canvas

如何設置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" >複製代碼

佈局bash

<?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>複製代碼

自定義View來解決GridView的分割線

效果圖
微信

Markdown
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);
            }
        }
    }
}複製代碼

咱們都知道這裏用到了dispatchDraw方法iview

/**
     * 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) {

    }複製代碼
  • 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.raride

相信本身,沒有作不到的,只有想不到的

若是你以爲此文對您有所幫助,歡迎入羣 QQ交流羣 :232203809
微信公衆號:終端研發部 佈局

技術+職場
技術+職場
相關文章
相關標籤/搜索