Customizing GridView to Realize Splitting Line Resolution

Keywords: Android xml encoding

Two days ago, when I met with some projects, I used GridView to realize some segmentation lines. Before that, I used this method to display segmentation lines by using different lines of background color of listView and Item. This is one of the low est practices. So I simply wrote a custom GridView.

Let's first see how List sets the partition line.
android:divider
android:dividerHeight

However, we all know that GirdView does not have grid lines by default, so how to set it up?

How to Set GridView's Split Line

  • The first acts as divier by setting different background colors
    • First set the background color of the GridView
    • Set the background color of item
    • Set the width and height of 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" >

layout

<?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="picture"/>
</LinearLayout>

Custom View Solves GridView Splitting Line

Design sketch

**
 *  Class Function Description:</br>
 * Created by Administrator on 2017/2/19 0018.
 * Blog address: http://blog.csdn.net/androidstarjack
 * @author androidstar
 * @version 1.0 </p> Modification time:</br> Amend Notes:</br>
 *  Public Number: Terminal R&D Department
 */

public class MyGridView extends GridView {
    /**
     * Default splitter color
     * You can also set it in the layout.
     */
    private int diverColor = R.color.color1;
    /**
     * Default partition line height
     * You can also set it in the layout.
     */
    private int diverHeight = 1;
    /**
     * Brushes used
     */
    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);
    }
    /**
     * Dynamically modify the default splitter color
     */
    public void setDiverColor(int diverColor){
        this.diverColor = diverColor;
        invalidate();
    }
    /**
     * Dynamically modify the default splitter color
     */
    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);//Get the first view
        int column = getWidth() / localView1.getWidth();//Column number
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View cellView = getChildAt(i);
            if ((i + 1) % column == 0) {//The last line in each line
                canvas.drawLine(cellView.getLeft(), cellView.getBottom(), cellView.getRight(), cellView.getBottom(), paint);
            } else if ((i + 1) > (childCount - (childCount % column))) {//item on the last line
                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);
            }
        }
    }
}

We all know that the dispatchDraw method is used here.

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

    }
  • Drawing of the View component calls draw(Canvas canvas) method. Drawing process mainly draws the Drawable background first, and then calls setBounds() and draw(Canvas c) method for drawable. It is noted that the actual size of the background drawable can affect the size of the view component. The actual size of the drawable is obtained by getIntrinsicWidth() and getIntrinsicHeight(), when the background is large, the view component is obtained by getIntrinsicWidth() and getIntrinsicHeight(). Size equals the size of background drawable
    After drawing the background, the drawing procedure calls the onDraw(Canvas canvas) method, and then the dispatchDraw(Canvas canvas) method.
  • dispatchDraw() is mainly distributed to sub-components for drawing. We usually rewrite the onDraw() method when we customize components. It is noteworthy that the drawing of the ViewGroup container component directly calls the dispatchDraw() method when it has no background, and bypasses the draw() method. When it has background, the draw() method calls the draw() method, and the draw() method contains the call of the dispatchDraw() method. So when drawing something on ViewGroup, it's often the dispatchDraw() method instead of onDraw() method, or customizing a Drawable, rewriting its draw(Canvas c) and getIntrinsicWidth().

Relevant demo now address:
MyGridViewApplication.rar

If you think this article is helpful to you, please join QQ group: 232203809
Wechat Public Number: Terminal R&D Department

(Welcome to study and exchange)

Posted by Ghostgator on Mon, 01 Apr 2019 21:12:30 -0700