圆形水波控件
圆形水波控件,看起来就觉得很牛b的样子。水波是利用贝塞尔曲线的原理绘制的。效果图如下:
看上去是不是很牛的样子,哈哈...
想都不用想这是一个自定义控件,如下:
public class WaveView extends View {
private static final int CONTROL_SIZE = 600; //控件大小
private Paint backgroundPaint;
private Paint firstWavePaint;
private Paint secondWavePaint;
private int backgroundColor;
private int firstWaveColor;
private int secondWaveColor;
private Path firstPath;
private Path secondPath;
private Bitmap bitmap;
private Canvas bitmapCanvas;
private int speed; //水波的速度
private int amplitude; //振幅 ---- 水波的最高点和最低点
private static final float palstance = 0.5F; //角速度
private static final float waterProgressMax = 100; //最高水位
private float waterProgress; //水位高度 --- 0~100
private int waveSize; //控件尺寸
private int angle;
private static final int whatStartWave = 100; //开始 波动水位
private WaveHandler waveHandler;
private WaveThread waveThread;
private boolean canLoopWave;
private String name = "电量";
private Paint textPaint;
private Rect rect;
public WaveView(Context context) {
super(context);
initView(null);
}
public WaveView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(waveSize, waveSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
firstPath.reset();
secondPath.reset();
bitmapCanvas.drawCircle(waveSize / 2, waveSize / 2, waveSize / 2, backgroundPaint);
/**水位线*/
float waterLine = (waterProgressMax - waterProgress) * waveSize * 0.01F;
/* x、y*/
firstPath.moveTo(0, waterLine);
secondPath.moveTo(0, waterLine);
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
for (int i = 0; i < waveSize; i++) { //x轴数据的集合
x1 = i;
x2 = i;
//轴数据对应的y值 --- 正弦曲线 y = sin(X);
y1 = (int) (amplitude * Math.sin((i * palstance + angle) * Math.PI / 180) + waterLine);
y2 = (int) (amplitude * Math.sin((i * palstance + angle - 90) * Math.PI / 180) + waterLine);
firstPath.quadTo(x1, y1, x1 + 1, y1);
secondPath.quadTo(x2, y2, x2 + 1, y2);
}
firstPath.lineTo(waveSize, waveSize);
firstPath.lineTo(0, waveSize);
firstPath.close();
secondPath.lineTo(waveSize, waveSize);
secondPath.lineTo(0, waveSize);
secondPath.close();
bitmapCanvas.drawPath(firstPath, firstWavePaint);
bitmapCanvas.drawPath(secondPath, secondWavePaint);
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
canvas.drawBitmap(bitmap, 0, 0, null);
String progress = (int) waterProgress + "%";
textPaint.getTextBounds(progress, 0, progress.length(), rect);
int progressWidth = rect.width();
textPaint.getTextBounds(name, 0, name.length(), rect);
int textWidth = rect.width();
textPaint.setTextSize(60);
if (waterProgress<35){
textPaint.setColor(Color.BLACK);
}else {
textPaint.setColor(Color.WHITE);
}
canvas.drawText(name, waveSize / 2 - textWidth / 2, waveSize * 3 / 4, textPaint); //把name画上去
if (waterProgress<70){
textPaint.setColor(Color.BLACK);
}else {
textPaint.setColor(Color.WHITE);
}
canvas.drawText(progress, waveSize / 2 - progressWidth / 2, waveSize * 2 / 5, textPaint); //画进度值
}
private void initView(AttributeSet attrs) {
angle = 360;
canLoopWave = true;
waterProgress = 0;
Context context = getContext();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.wave_view);
backgroundColor = typedArray.getColor(R.styleable.wave_view_backgroundColor, Color.parseColor("#44EEEEEE"));
firstWaveColor = typedArray.getColor(R.styleable.wave_view_firstWaveColor, Color.parseColor("#C3F5FE"));
secondWaveColor = typedArray.getColor(R.styleable.wave_view_secondWaveColor, Color.parseColor("#43DCFE"));
waterProgress = typedArray.getFloat(R.styleable.wave_view_waterProgress, 0);
amplitude = typedArray.getInt(R.styleable.wave_view_amplitude, dpToPx(20));
speed = typedArray.getInt(R.styleable.wave_view_speed, 1);
waveSize = typedArray.getDimensionPixelSize(R.styleable.wave_view_waveSize, CONTROL_SIZE);
waveThread = new WaveThread();
waveHandler = new WaveHandler();
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
backgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
backgroundPaint.setColor(backgroundColor);
backgroundPaint.setAntiAlias(true);
bitmap = Bitmap.createBitmap(waveSize, waveSize, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
bitmapCanvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
/*初始化波浪画笔*/
firstWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
firstWavePaint.setAntiAlias(true);
firstWavePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
firstWavePaint.setColor(firstWaveColor);
/**
* 该方法用来设置两张图片相交时的模式
* SRC_ATOP : 取下层非交集部分与上层交集部分
*/
firstWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
secondWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
secondWavePaint.setAntiAlias(true);
secondWavePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
secondWavePaint.setColor(secondWaveColor);
secondWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
firstPath = new Path();
secondPath = new Path();
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setAntiAlias(true);
textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.BLACK);
rect = new Rect(); //创建矩形对象
waveThread.start(); //开启线程
}
public void startThread() {
if (waveThread != null && waveThread.isInterrupted()) {
waveThread.start();
}
}
/**
* 设置 水位的进度 [0-100]
* @param waterProgress 水位进度
*/
public WaveView setWaterProgress(float waterProgress) {
if (waterProgress <= 0) {
waterProgress = 0;
} else if (waterProgress >= 100) {
waterProgress = 100;
}
this.waterProgress = waterProgress;
invalidate();
return this;
}
/**
* 设置第一条波浪线的 颜色
*/
public WaveView setFirstWaveColor(int firstWaveColor) {
this.firstWaveColor = firstWaveColor;
firstWavePaint.setColor(firstWaveColor);
invalidate();
return this;
}
/**
* 设置第二条波浪线的 颜色
*/
public WaveView setSecondWaveColor(int secondWaveColor) {
this.secondWaveColor = secondWaveColor;
secondWavePaint.setColor(secondWaveColor);
invalidate();
return this;
}
/**
* 设置 波动速读
*/
public WaveView setSpeed(int speed) {
if (speed < 1) {
speed = 1;
}
if (speed > 10) {
speed = 10;
}
this.speed = speed;
return this;
}
/**
* 波浪 波动的 线程
*/
private class WaveThread extends Thread {
@Override
public void run() {
super.run();
while (canLoopWave) {
angle = angle - 1 * speed;
if (angle == 0) {
angle = 360;
}
waveHandler.removeCallbacksAndMessages(null);
waveHandler.sendEmptyMessage(whatStartWave);
SystemClock.sleep(10);
}
}
}
/**
* 波浪 波动的 操作者
*/
private class WaveHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (whatStartWave == msg.what) {
invalidate();
}
}
}
/**
* 设置 振幅
* @param amplitude 单位 dp
*/
public WaveView setAmplitude(int amplitude) {
if (amplitude <= 0) {
amplitude = 0;
}
this.amplitude = amplitude;
invalidate();
return this;
}
/**
* 数据转换: dp---->px
*/
private int dpToPx(float dp) {
return (int) (dp * getContext().getResources().getDisplayMetrics().density);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopThread();
}
public void stopThread() {
canLoopWave = false;
if (waveThread != null) {
waveThread.interrupt();
waveThread = null;
}
if (waveHandler != null) {
waveHandler.removeMessages(whatStartWave);
waveHandler = null;
}
}
}
<resources>
<declare-styleable name="wave_view">
<attr name="backgroundColor" format="color" />
<attr name="firstWaveColor" format="color" />
<attr name="secondWaveColor" format="color" />
<attr name="waveSize" format="dimension" />
<attr name="waterProgress" format="float" />
<!-- 10 到 50之间比较合适-->
<attr name="amplitude" format="integer" />
<!-- 1 到 6 之间比较合适 -->
<attr name="speed" format="integer" />
</declare-styleable>
</resources>
handler.postDelayed(new Runnable() {
@Override
public void run() {
progress++;
wv.setWaterProgress(progress);
if (progress <100){
if (progress <= 20){
wv.setFirstWaveColor(0xfffda8a8);
wv.setSecondWaveColor(0xffff0000);
}else {
wv.setFirstWaveColor(0xffacfdac);
wv.setSecondWaveColor(0xff00ff00);
}
method();
}else {
wv.setSpeed(0);
wv.setAmplitude(0);
}
}
},500);