自定义绘图View之onDraw

1,上一两个demo简单说明一下吧

第一个绘一个实时的钟表:

具体代码:

package demo.com.customviewdemo;

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 java.util.Calendar;

/**
 * Created by Alv_chi 
 */
public class MyClockView extends View {

    private Paint circlePaint;
    private Paint pointerPaint;
    private Paint textPaint;


    public MyClockView(Context context) {
        this(context, null);
    }

    public MyClockView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyClockView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public MyClockView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
//     初始化画笔工具:
        initialPaints();

    }

    private void initialPaints() {
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(Color.CYAN);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(10);
        pointerPaint = new Paint();
        pointerPaint.setColor(Color.GREEN);
        textPaint = new Paint();
        textPaint.setColor(Color.RED);
        textPaint.setTextSize(30);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//     计算圆心坐标,和半径;
        int height = getHeight();
        int width = getWidth();
        int centerY = height / 2;
        int centerX = width / 2;
        int radius = (height > width ? width : height) / 4;

//        画个圆,和圆心;
        canvas.drawCircle(centerX, centerY, radius, circlePaint);
        canvas.drawPoint(centerX, centerY, circlePaint);

//        画钟表上的数字:
        double singleAngle = Math.PI * 2 / 12;
        for (int i = 1; i < 13; i++) {
            float textSize = textPaint.measureText(i + "", 0, (i + "").length());
            double deltaAngle = singleAngle * i;
            double y = centerY - radius * Math.cos(deltaAngle)+textSize/2;
            double x = centerX + radius * Math.sin(deltaAngle)-textSize/2;

            canvas.drawText(i + "", (float) x, (float) y, textPaint);

        }

//        画时针,分针,秒针:
        Calendar calendar = Calendar.getInstance();
        int second = calendar.get(Calendar.SECOND);
        int minute = calendar.get(Calendar.MINUTE);
        int hour = calendar.get(Calendar.HOUR);
        float fhour =  hour+ minute / 60f;


//        时针
        pointerPaint.setStrokeCap(Paint.Cap.ROUND);
        pointerPaint.setStrokeWidth(20);
        canvas.drawLine(centerX, centerY, (float) (centerX + radius * 0.45 * Math.sin(Math.toRadians(fhour * 30))), (float) (centerY - (radius * 0.5 * Math.cos(Math.toRadians(fhour * 30)))), pointerPaint);


//        分针
        pointerPaint.setStrokeWidth(10);
        canvas.drawLine(centerX, centerY, (float) (centerX + radius * 0.6 * Math.sin(Math.toRadians(minute * 6))), (float) (centerY - (radius * 0.8 * Math.cos(Math.toRadians(minute * 6)))), pointerPaint);

//        秒针
        pointerPaint.setStrokeWidth(3);
        canvas.drawLine(centerX, centerY, (float) (centerX + radius * 0.8 * Math.sin(Math.toRadians(second * 6))), (float) (centerY - (radius * 0.8 * Math.cos(Math.toRadians(second * 6)))), pointerPaint);

//        每隔1秒重绘刷新一次;
        postInvalidateDelayed(1000);
    }


}
效果如图:



2;第二个例子是以一个正五边形和五角星:

package demo.com.customviewdemo;

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

/**
 * Created by Alv_chi 
 */
public class MyFiveStarView extends View{

    private Paint paint;
    private double[] arrY;
    private double[] arrX;
    private Path path;
    private double[] X;
    private double[] Y;


    public MyFiveStarView(Context context) {
        this(context,null);
    }

    public MyFiveStarView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyFiveStarView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr,0);
    }

    public MyFiveStarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        paint = new Paint();
        paint.setColor(Color.CYAN);
        paint.setStrokeWidth(20);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int height = getHeight();
        int width = getWidth();
        int centerY = height / 2;
        int centerX = width / 2;
        int radius = (height > width ? width : height) / 4;

        initialPointArr(centerY, centerX, radius);
//      画正五边形:
//        drawGraphic(canvas,arrX,arrY);

//        改变一下数组坐标顺序,就可以画个五角星:
        drawGraphic(canvas,X,Y);
    }

    private void drawGraphic(Canvas canvas,double[] X,double[] Y) {
        path = new Path();


        for (int i = 0; i < 5; i++) {
            if (i==0)
            {
                path.moveTo((float) X[i], (float) Y[i]);

            }else
            {
                path.lineTo((float) X[i], (float) Y[i]);

            }
        }

        path.close();

        canvas.drawPath(path,paint);
    }

    private void initialPointArr(int centerY, int centerX, int radius) {

//        从最高顶点开始,从左往右开始计算各个顶点的坐标;
//        顶点坐标:
        double tX = centerX;
        double tY = centerY - radius;

//        右中顶点坐标:
        double rmY = centerY-radius *Math.sin(Math.toRadians(18));
        double rmX = tX + radius * Math.cos(Math.toRadians(18));

//        右底顶点坐标:
        double rbY = centerY + radius * Math.cos(Math.toRadians(36));
        double rbX = centerX + radius *Math.sin(Math.toRadians(36));;

//        相对应的左边中底顶点坐标为:
        double lmY = rmY;
        double lmX = tX -radius * Math.cos(Math.toRadians(18));

        double lbY = rbY;
        double lbX = centerX - radius *Math.sin(Math.toRadians(36));

//        分别用两数组对应地装起来;
        arrY = new double[]{tY,rmY,rbY,lbY,lmY};
        arrX = new double[]{tX,rmX,rbX,lbX,lmX};
//      改变数组顺序:
        X = new double[]{lbY,tY,rbY,lmY,rmY};
        Y = new double[]{lbX,tX,rbX,lmX,rmX};
    }
}

效果如图:





总结;  先是准备好画笔,再计算出相应坐标位置(x,y),最后用相应的Draw方法去绘,不难,主要是数学计算和相关Api的运用,api不懂可以直接看源码;


最后源码下载:点击打开链接下载源码


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android自定义View中的Canvas是一个绘图容器,可以在其上进行2D绘图操作。通过Canvas,我们可以绘制图形、文字、位图等。 要在自定义View中使用Canvas,需要重写ViewonDraw()方法,并在该方法中获取Canvas实例,然后进行绘制操作。 下面是一个简单的示例代码,展示如何在自定义View中使用Canvas绘制一个矩形: ```java public class MyCustomView extends View { public MyCustomView(Context context) { super(context); } public MyCustomView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); canvas.drawRect(100, 100, 300, 300, paint); } } ``` 在这个示例中,我们创建了一个名为MyCustomView自定义View,并重写了它的onDraw()方法。在该方法中,我们首先创建了一个Paint对象,设置了画笔的颜色为红色,并指定绘制的样式为填充。然后,使用Canvas的drawRect()方法绘制一个矩形,坐标为(100, 100)到(300, 300)。 当我们在布局文件中使用这个自定义View时,它会自动调用onDraw()方法进行绘制,从而在屏幕上显示出红色矩形。 需要注意的是,Canvas提供了许多其他绘制方法,如drawCircle()、drawText()等,可以根据需求选择合适的方法进行绘制操作。此外,还可以通过设置Paint对象的属性来实现不同的绘制效果,如线条宽度、字体大小等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值