自定义View之实现一个简单的圆

1.引入布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.MainActivity">

    <com.example.myapplication.Activity.CustomCircleView
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</LinearLayout>

2.自定义圆形类文件:

package com.example.myapplication.Activity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class CustomCircleView extends View {

    //构造函数
    public CustomCircleView(Context context) {
        super(context);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * 重写onDraw()方法
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //获取画笔
        Paint paint = new Paint();

        //定义画笔的颜色
        paint.setColor(Color.RED);

        //获取画布的宽度
        int width = getWidth();

        //获取画布的高度
        int height = getHeight();

        //画一个离原点(左上角)宽距:100 高距:100 半径:100的圆
        canvas.drawCircle(100,100,100,paint);

        //画一个最大化画布的圆形
        canvas.drawCircle(width/2,height/2,Math.min(width,height)/2,paint);
    }
}

3.实现的效果如下:

4.修改引入布局的相关参数,验证padding、margin、wrap_content等是否有效,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.MainActivity">

    <com.example.myapplication.Activity.CustomCircleView
        android:layout_width="wrap_content"
        android:background="@color/black"
        android:layout_margin="20dp"
        android:padding="20dp"
        android:layout_height="200dp"/>


</LinearLayout>

5.验证结果如下,得出结论:margin有效、padding无效、wrap_content无效,结果如图所示:

6.为了使得padding生效,修改自定义圆形类文件,如下所示:

package com.example.myapplication.Activity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class CustomCircleView extends View {

    //构造函数
    public CustomCircleView(Context context) {
        super(context);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * 重写onDraw()方法
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //获取左边padding
        int paddingLeft = getPaddingLeft();

        //获取右边padding
        int paddingRight = getPaddingRight();

        //获取顶部的padding
        final int paddingTop = getPaddingTop();

        //获取底部的padding
        final int paddingBottom = getPaddingBottom();

        //获取画笔
        Paint paint = new Paint();

        //定义画笔的颜色
        paint.setColor(Color.RED);

        //获取画布的宽度
        int width = getWidth()-paddingLeft-paddingRight;

        //获取画布的高度
        int height = getHeight()-paddingTop-paddingBottom;

        //画一个离原点(左上角)宽距:100 高距:100 半径:100的圆
        canvas.drawCircle(paddingLeft+100,paddingTop+100,100,paint);

        //画一个最大化画布的圆形
        canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2,Math.min(width,height)/2,paint);
    }
}

7.运行结果如下所示,可以看出padding已经生效了:

8.为了更好地显示修改代码所带来的效果,将固定宽高的小圆进行删除,重写onMeasure()方法,并且设置wrap_content的默认值,代码结果如下(其实将默认值设置大一些,也是可以将小圆放置进去的,但是这样效果就不明显了):

package com.example.myapplication.Activity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;

public class CustomCircleView extends View {

    //构造函数
    public CustomCircleView(Context context) {
        super(context);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //构造函数
    public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }


    /**
     * 重写onMeasure()方法
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 获取宽的测量规格的模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        // 获取宽的测量规格的大小
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        // 获取高-测量规格的模式
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        // 获取高-测量规格的大小
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        // wrap_content的默认宽 / 高值
        int mWidth = 400;
        int mHeight = 400;

        if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT && getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(mWidth, mHeight);
        } else if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(mWidth, heightSize);
        } else if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(widthSize, mHeight);
        }
    }


    /**
     * 重写onDraw()方法
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //获取左边padding
        int paddingLeft = getPaddingLeft();

        //获取右边padding
        int paddingRight = getPaddingRight();

        //获取顶部的padding
        final int paddingTop = getPaddingTop();

        //获取底部的padding
        final int paddingBottom = getPaddingBottom();

        //获取画笔
        Paint paint = new Paint();

        //定义画笔的颜色
        paint.setColor(Color.RED);

        //获取画布的宽度
        int width = getWidth() - paddingLeft - paddingRight;

        //获取画布的高度
        int height = getHeight() - paddingTop - paddingBottom;

        //画一个离原点(左上角)宽距:100 高距:100 半径:100的圆
        //canvas.drawCircle(paddingLeft+100,paddingTop+100,100,paint);

        //画一个最大化画布的圆形
        canvas.drawCircle(paddingLeft + width / 2, paddingTop + height / 2, Math.min(width, height) / 2, paint);
    }
}

9.运行结果如图所示:

猜你喜欢

转载自blog.csdn.net/xiaokang666/article/details/127936979