效果展示:
效果展示1
效果展示2
效果展示3
代碼:
創(chuàng)建TestView類:
package swu.twj.a13_drawview;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.Timer;
import java.util.TimerTask;
/**
* 餅狀圖
*/
public class TestView extends View {
int startAngle = 0;
int angle;//每一次增長(zhǎng)之后的值
int speed = 10;//增長(zhǎng)速度
public TestView(Context context) {
super(context);
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(Color.GRAY);
}
/**
* 當(dāng)繼承于ViewGroup的時(shí)候
* @param widthMeasureSpec 父控件預(yù)測(cè)的這個(gè)控件的最大寬度
* @param heightMeasureSpec 父控件預(yù)測(cè)的這個(gè)控件的最大高度
*/
@Override
//測(cè)量:設(shè)置視圖控件的具體尺寸
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//固定的尺寸 - 自己設(shè)定寬高
//setMeasuredDimension(100,100);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
/*
//創(chuàng)建定時(shí)器 每隔0.3s畫一次
final Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
angle += speed;
//控制最大值
if (angle > 360){
t.cancel();//關(guān)閉定時(shí)器
}
invalidate();//通知系統(tǒng)調(diào)用onDraw
//postInvalidate();//子線程里面
}
},0,300);
*/
//屬性動(dòng)畫
//ObjectAnimator
//ValueAnimator 監(jiān)聽動(dòng)畫過程中某個(gè)值的改變過程
//angle 0 - 360
ValueAnimator va = ValueAnimator.ofInt(0,360);
va.setDuration(1000);
va.setRepeatCount(ValueAnimator.INFINITE);
va.setRepeatMode(ValueAnimator.REVERSE);
//設(shè)置監(jiān)聽器 監(jiān)聽值的變化
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//獲取某一刻的值
angle = (int)valueAnimator.getAnimatedValue();
//刷新
invalidate();
}
});
//啟動(dòng)
va.start();
}
/**
* 如果自定義的視圖
* 形狀無規(guī)則
* 用特定的方式顯示內(nèi)容
* 完成特定功能
* @param canvas 默認(rèn)提供的一個(gè)畫布
* 將需要的內(nèi)容畫到畫布上 統(tǒng)一 渲染到界面上GPU
* 缺點(diǎn):如果頻繁繪制 內(nèi)存吃緊
*
* 能夠使用系統(tǒng)的就不要自己繪制
*/
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
//畫一條線
//1.準(zhǔn)備畫筆
Paint mPaint = new Paint();
mPaint.setColor(Color.BLACK);//畫筆顏色
mPaint.setStrokeWidth(20);//畫筆的粗細(xì)
mPaint.setAntiAlias(true);//抗鋸齒
//mPaint.setStyle(Paint.Style.STROKE);//設(shè)置空心
mPaint.setStyle(Paint.Style.FILL);//設(shè)置實(shí)心
//2.畫線
//canvas.drawLine(100,100,800,800,mPaint);
//3.畫圓
//canvas.drawArc(50,100,350,400,0,270,true,mPaint);
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
angle += speed;
//控制最大值
if (angle > 360){
angle = 360;
}
invalidate();
}
},0,500);
drawPieChart(canvas,Color.MAGENTA,(float)(angle/360.0));
//drawPieChart(canvas,Color.BLUE,(float)(1/4.0));
//drawPieChart(canvas,Color.GREEN,(float)(1/4.0));
//drawPieChart(canvas,Color.RED,(float)(1/4.0));
}
//畫餅狀圖
private void drawPieChart(Canvas canvas,int color,float rate){
//畫筆
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
//畫扇形
int endAngle = (int)(360*rate);
canvas.drawArc(50,100,550,600,0,endAngle,true,paint);
startAngle += endAngle;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
//點(diǎn)擊屏幕 畫一點(diǎn)
angle += speed;
//控制最大值
if (angle > 360){
angle = 360;
}
//告訴系統(tǒng)調(diào)用onDraw方法實(shí)現(xiàn)繪制
invalidate();
}
return true;
}
}
xml文件配置:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<swu.twj.a13_drawview.TestView
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</RelativeLayout>