三个类源码地址:http://download.csdn.net/detail/fkgjdkblxckvbxbgb/9731656
一下班就迫不及待的想完成那个界面,我去看了一下,这次更新的支付宝芝麻信用,貌似没有特效,我觉得不好,就自己加上了.来,先看看效果图
思路
1:因为半圆只有280度,但是主界面传过来的值是0~100之间的数字,所以绘制的弧形 progress*280/100 .这才是我们要的弧度,
2:外圈的颜色渐变 , 用的是梯阶渐变 , Shader mShader = new SweepGradient(); 大家有空去研究下
3:然后就是背景色的渐变,其实是可以放在View里面去重绘的,我把它拿出来直接在Activity回调中区变色 . 根据绘图回传的进度值,来变色
4:文字描述,也是根据传入的数值来变动,如果需要动态显示,可以自己去重绘下,我觉得没什么必要,变化太少,还不如不变
是不是有点小激动呢 ? 我个人觉得比还不错 . 来,不废话了,看代码 . 基本功能这里不多讲,主要说说动画绘制的思路,以及特效的方法,和遇到的麻烦,代码看起来有些绕,最好是自己写,然后再来看 .
============布局文件============
======主界面代码===========
package com.cdl.demo;
import com.cdl.demo.PayView.ChangeBgListener;
import android.animation.ArgbEvaluator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
public class MainActivity extends Activity implements ChangeBgListener {
PayView myview;
Button btn_text;
EditText et_num;
private RelativeLayout rela_bgg;
private int maxNum = 100;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pay);
rela_bgg = (RelativeLayout) findViewById(R.id.rela_bgg);
myview = (PayView) findViewById(R.id.myview);
myview.setOnChangeListener(this);
myview.setProgress(80);
}
@Override
public void changeBg(int progress) {
rela_bgg.setBackgroundColor(calculateColor(progress));
System.out.println("==" + progress);
}
@SuppressLint("NewApi")
private int calculateColor(int value) {
ArgbEvaluator evealuator = new ArgbEvaluator();
float fraction = 0;
int color = 0;
if (value <= maxNum / 2) {
fraction = (float) value / (maxNum / 2);
color = (Integer) evealuator.evaluate(fraction, 0xFFFF6347, 0xFFFF8C00); // 由红到橙
} else {
fraction = ((float) value - maxNum / 2) / (maxNum / 2);
color = (Integer) evealuator.evaluate(fraction, 0xFFFF8C00, 0xFF00CED1); // 由橙到蓝
}
return color;
}
}
====================View====代码
package com.cdl.demo;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
public class PayView extends View {
Paint mPaint;
Paint changePaint; // 变色处理
// 换算角度的进度
int progress_change = 0;
// 用于变量的progress
int progress;
String CONTENT_TEXT = "信用极好";
String BETA = "BETA";
String TEXT_TIME = "评估时间 : 8888-88-88";
int COLOR_WHITE = 0xffFFFFFF;
float PROGRESS_WIDTH = 5;
private int circleRadius = 200;
/** 起始绘制的角度位置 */
private int START_CANVAS = 130;
/** 总数旋转的角度 */
private int ROTATE_NUM = 280;
String CONTENT_NUM = "0";
int currentProgress = 0;
public void setProgress(int progress) {
this.progress = progress;
changText(progress);
invalidate();
}
@SuppressLint("SimpleDateFormat")
private void changText(int progress2) {
if (progress2 > 0 && progress2 <= 40) {
CONTENT_TEXT = "信用极差";
} else if (progress2 > 40 && progress2 <= 60) {
CONTENT_TEXT = "信用一般";
} else if (progress2 > 60 && progress2 <= 80) {
CONTENT_TEXT = "信用良好";
} else if (progress2 > 80 && progress2 <= 100) {
CONTENT_TEXT = "信用极好";
}
// 显示评估的时间
SimpleDateFormat myFmt = new SimpleDateFormat("yyyy-MM-dd");
String time = myFmt.format(new Date());
TEXT_TIME = "评估时间 : " + time;
}
public PayView(Context context) {
this(context, null);
}
public PayView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PayView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
intiView();
}
private void intiView() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeCap(Cap.ROUND);
changePaint = new Paint();
changePaint.setAntiAlias(true);
changePaint.setDither(true);// 设置抖动,颜色过渡更均匀
changePaint.setStrokeCap(Cap.ROUND);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBg(canvas); // 绘制外围的暗色半圆
drawPoint(canvas); // 绘制内圈的暗色点
drawTitleText(100, BETA, canvas); // 绘制beta
drawContent(canvas); // 绘制主题文字
drawNum(canvas); // 绘制progress文字_________________需要重绘
drawTitleText(270, TEXT_TIME, canvas); // 绘制beta
drawBgChange(canvas); // 绘制外围变色区域__________需要重绘
drawPointLight(canvas); // 绘制亮点__________需要重绘
drawPointTo(canvas); // 指向点的位置_________________需要重绘
if (currentProgress < progress) {
currentProgress++;
CONTENT_NUM = currentProgress + "";
// 角度280.换算成100分来算
progress_change = currentProgress * ROTATE_NUM / 100;
// 回调接口,用于背景渐变
listener.changeBg(currentProgress);
invalidate();
}
}
// 外围渐变色
private void drawBgChange(Canvas canvas) {
changePaint.setStyle(Paint.Style.STROKE);
changePaint.setStrokeWidth(PROGRESS_WIDTH);
changePaint.setAlpha(255);
// 梯度渐变色.类似雷达扫描
Shader mShader = new SweepGradient(getWidth() / 2, getHeight() / 2, new int[] { 0x00000000, 0xffffffff },
new float[] { START_CANVAS, START_CANVAS + ROTATE_NUM });
changePaint.setShader(mShader);
int width = getWidth();
int height = getHeight();
int left = width / 2 - circleRadius;
int top = height / 2 - circleRadius;
int right = width / 2 + circleRadius;
int bottom = height / 2 + circleRadius;
RectF oval1 = new RectF(left, top, right, bottom);
canvas.drawArc(oval1, START_CANVAS, progress_change, false, changePaint);// 小弧形
}
// 绘制秒速文字
private void drawNum(Canvas canvas) {
final int width = getWidth();
final int height = getHeight();
final Rect bounds = new Rect();
mPaint.setColor(COLOR_WHITE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(55);
mPaint.setAlpha(250); // 透明度值在0~255之间
mPaint.getTextBounds(CONTENT_NUM, 0, CONTENT_NUM.length(), bounds);
canvas.drawText(CONTENT_NUM, (width / 2) - (bounds.width() / 2), (height / 2) - circleRadius + 220, mPaint);
}
// 绘制信用很好
private void drawContent(Canvas canvas) {
final int width = getWidth();
final int height = getHeight();
final Rect bounds = new Rect();
mPaint.setColor(COLOR_WHITE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(35);
mPaint.setAlpha(180); // 透明度值在0~255之间
mPaint.getTextBounds(CONTENT_TEXT, 0, CONTENT_TEXT.length(), bounds);
canvas.drawText(CONTENT_TEXT, (width / 2) - (bounds.width() / 2), (height / 2) - circleRadius + 150, mPaint);
}
private void drawTitleText(int distance, String textD, Canvas canvas) {
final int width = getWidth();
final int height = getHeight();
final Rect bounds = new Rect();
mPaint.setColor(COLOR_WHITE);
mPaint.setAlpha(255);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(25);
mPaint.setAlpha(130); // 透明度值在0~255之间
mPaint.getTextBounds(textD, 0, textD.length(), bounds);
canvas.drawText(textD, (width / 2) - (bounds.width() / 2), (height / 2) - circleRadius + distance, mPaint);
}
/**
* 绘制指向点
*/
@SuppressLint("NewApi")
private void drawPointTo(Canvas canvas) {
canvas.save();
mPaint.setStyle(Paint.Style.FILL);
int startX = getWidth() / 2;
int startY = getHeight() / 2;
int piont_num = ROTATE_NUM / 4;
int changeCircle = progress_change * piont_num / ROTATE_NUM;
// 图片和圆点偏差3度的角度,这里少转3度
canvas.rotate(START_CANVAS - 3, startX, startY);// 以圆中心进行旋转
for (int i = 0; i < piont_num; i++) {
if (i == changeCircle) {
Bitmap map = BitmapFactory.decodeResource(getResources(), R.drawable.ccc);
canvas.drawBitmap(map, startX + circleRadius - 50, startY, mPaint);
}
canvas.rotate(degree, startX, startY);// 以圆中心进行旋转
}
canvas.restore();
}
/**
* 绘制指向点
*/
@SuppressLint("NewApi")
private void drawPointLight(Canvas canvas) {
canvas.save();
mPaint.setColor(COLOR_WHITE);
mPaint.setStyle(Paint.Style.FILL);
int startX = getWidth() / 2;
int startY = getHeight() / 2;
int piont_num = ROTATE_NUM / degree;
int changeCircle = progress_change * piont_num / ROTATE_NUM;
canvas.rotate(START_CANVAS, startX, startY);// 以圆中心进行旋转
for (int i = 0; i < piont_num; i++) {
if (i < changeCircle + 1) {
canvas.drawCircle(startX + circleRadius - 20, startY, 3, mPaint);
}
canvas.rotate(degree, startX, startY);// 以圆中心进行旋转
}
canvas.restore();
}
/**
* 绘制一圈的点.每4度画一个点
*/
int degree = 4;
private void drawPoint(Canvas canvas) {
canvas.save();
mPaint.setColor(COLOR_WHITE);
mPaint.setAlpha(80);
mPaint.setStyle(Paint.Style.FILL);
int startX = getWidth() / 2;
int startY = getHeight() / 2;
// 点的格式
int piont_num = ROTATE_NUM / degree;
canvas.rotate(START_CANVAS, startX, startY);// 以圆中心进行旋转
for (int i = 0; i < piont_num; i++) {
canvas.drawCircle(startX + circleRadius - 20, startY, 3, mPaint);
canvas.rotate(degree, startX, startY);// 以圆中心进行旋转
}
canvas.restore();
}
/***
* 绘制外围的线
*
* @param canvas
*/
private void drawBg(Canvas canvas) {
mPaint.setColor(COLOR_WHITE);
mPaint.setAlpha(50);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(PROGRESS_WIDTH);
int width = getWidth();
int height = getHeight();
int left = width / 2 - circleRadius;
int top = height / 2 - circleRadius;
int right = width / 2 + circleRadius;
int bottom = height / 2 + circleRadius;
RectF oval1 = new RectF(left, top, right, bottom);
canvas.drawArc(oval1, START_CANVAS, ROTATE_NUM, false, mPaint);// 小弧形
}
ChangeBgListener listener;
public void setOnChangeListener(ChangeBgListener listener) {
this.listener = listener;
}
public interface ChangeBgListener {
void changeBg(int progress);
}
}