自定义view简单例子

自定义view简单例子

本文主要讲解View的绘制,主要重写view的onDraw方法。效果图如下:
这里写图片描述
自定义绘制View,就少不了画笔Paint,这里简单介绍一下Paint:

  • paint.setAntiAlias(true);//抗锯齿功能
  • paint.setColor(Color.RED); //设置画笔颜色
  • paint.setStyle(Style.FILL);//设置填充样式(有几种样式)
  • paint.setStrokeWidth(10);//设置画笔宽度
  • paint.setShadowLayer(10, 15, 15, Color.GREEN);//设置阴影

下面开始自定义View之旅,首先要创建一个视图类,继承自View,添加相应的构造方法。如下:

public CoustomView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    initPaint();
}

public CoustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
    initPaint();
}

其中initPaint是自己定义的初始化画笔方法,用于绘制图形。代码如下:

private void initPaint() {
    // TODO Auto-generated method stub
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    mPaint.setStrokeWidth(1);
    mPaint.setColor(Color.GREEN);
}

接下来就是绘制view主要的方法onDraw,此方法利用Canvas和Paint绘制你想要的图形。本文主要使用Canva绘制圆,他还有其他的绘制方法,不在这里一一介绍了。onDraw核心代码如下:

@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);

    //确定大圆半径最大范围
    int maxRadius= getWidth() < getHeight() ? getWidth()/2 : getHeight()/2;
    bigRadius = maxRadius *3/4;
    //绘制圆上的小球
    smallRadius = maxRadius *1/8;//小球半径
    float angle = 0;
    for (int i = 0; i < 8; i++) {
        //根据角度计算小球在圆上的坐标
        float x = (float) (getWidth()/2 + bigRadius*Math.cos(Math.toRadians(angle)));
        float y = (float) (getHeight()/2 + bigRadius*Math.sin(Math.toRadians(angle)));
        canvas.drawCircle(x, y, smallRadius, mPaint);
        angle += 45;

        if (points[7] == null) {
            CirclePoint point = new CirclePoint(x, y);
            points[i] = point;
        }
    }
    //移动小球的移动速度
    movingAngle += 3;
    绘制移动小球
    drawMovingCircle(canvas, movingAngle, bigRadius);

    invalidate();
}

下面介绍移动小球的绘制以及与圆上小球相交后的放大处理。主要方法:

/**
 * 移动的小球
 * @param canvas
 * @param angle
 * @param bigRadius
    */
private void drawMovingCircle(Canvas canvas,float angle,int bigRadius) {
    float x = (float) (getWidth()/2 + bigRadius*Math.cos(Math.toRadians(angle)));
    float y = (float) (getHeight()/2 + bigRadius*Math.sin(Math.toRadians(angle)));
    canvas.drawCircle(x, y, bigRadius *1/8, mPaint);

    for (int i = 0; i < points.length; i++) {
        //相交判断
        if (isIntersect(new CirclePoint(x, y), points[i])) {
            canvas.drawCircle(points[i].x, points[i].y, smallRadius +5, mPaint);//加大半径
        }
    }

}

判断两圆相交的方法

/**
 * 两圆相交
 * @param circlePoint
 * @param bigCirclePoint
    * @return
    */
private boolean isIntersect(CirclePoint circlePoint,CirclePoint bigCirclePoint) {
    float distance = (float) Math.sqrt((circlePoint.x - bigCirclePoint.x)*(circlePoint.x - bigCirclePoint.x) + (circlePoint.y - bigCirclePoint.y)*(circlePoint.y - bigCirclePoint.y));;
    return distance <  (bigRadius *1/8 + smallRadius);
}

至此自定义绘制view就完成了,下面附上全部代码:

package com.example.customviewgroup;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff.Mode;
import android.location.Criteria;
import android.util.AttributeSet;
import android.view.View;

@SuppressLint("DrawAllocation")
public class CoustomView extends View {
    private Paint mPaint;
    private int bigRadius;//大圆半径
    private int smallRadius;//小圆半径
    private float movingAngle =0;//小球移动角度
    private CirclePoint [] points = new CirclePoint[8];
    public CoustomView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initPaint();
    }

    public CoustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        initPaint();
    }
    private void initPaint() {
        // TODO Auto-generated method stub
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStrokeWidth(1);
        mPaint.setColor(Color.GREEN);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);

        //确定大圆半径最大范围
        int maxRadius= getWidth() < getHeight() ? getWidth()/2 : getHeight()/2;
        bigRadius = maxRadius *3/4;
        //绘制圆上的小球
        smallRadius = maxRadius *1/8;;
        float angle = 0;
        for (int i = 0; i < 8; i++) {
            float x = (float) (getWidth()/2 + bigRadius*Math.cos(Math.toRadians(angle)));
            float y = (float) (getHeight()/2 + bigRadius*Math.sin(Math.toRadians(angle)));
            canvas.drawCircle(x, y, smallRadius, mPaint);
            angle += 45;

            if (points[7] == null) {
                CirclePoint point = new CirclePoint(x, y);
                points[i] = point;
            }
        }
        movingAngle += 3;

        drawMovingCircle(canvas, movingAngle, bigRadius);

        invalidate();
    }

    /**
     * 移动的小球
     * @param canvas
     * @param angle
     * @param bigRadius
     */
    private void drawMovingCircle(Canvas canvas,float angle,int bigRadius) {
        float x = (float) (getWidth()/2 + bigRadius*Math.cos(Math.toRadians(angle)));
        float y = (float) (getHeight()/2 + bigRadius*Math.sin(Math.toRadians(angle)));
        canvas.drawCircle(x, y, bigRadius *1/8, mPaint);

        for (int i = 0; i < points.length; i++) {
            if (isIntersect(new CirclePoint(x, y), points[i])) {
                canvas.drawCircle(points[i].x, points[i].y, smallRadius +5, mPaint);
            }
        }

    }

    /**
     * 两圆相交
     * @param circlePoint
     * @param bigCirclePoint
     * @return
     */
    private boolean isIntersect(CirclePoint circlePoint,CirclePoint bigCirclePoint) {
        float distance = (float) Math.sqrt((circlePoint.x - bigCirclePoint.x)*(circlePoint.x - bigCirclePoint.x) + (circlePoint.y - bigCirclePoint.y)*(circlePoint.y - bigCirclePoint.y));;
        return distance <  (bigRadius *1/8 + smallRadius);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    class CirclePoint{
        float x,y;
        public CirclePoint(float x,float y) {
            // TODO Auto-generated constructor stub
            this.x = x;
            this.y = y;
        }
    }
}

项目地址 https://github.com/mengliguhun/MyProject

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值