自定义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;
}
}
}