版权声明:本文为博主原创文章,转载需注明博主文章链接。 https://blog.csdn.net/black_bread/article/details/63254487
偷了张效果图:
看完参考链接之后,发现效率有点差了,每次都绘制2*屏幕宽度次的line,强迫症的我啊。。
方法一:
每次都绘制line来生成图片也太鸡肋了,在onSizeChange中生成一张Bitmap用于onDraw方法中
onSizeChange方法
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
mWave = new int[mWidth];
float period = (float) (2 * Math.PI / mWidth);
for (int index = 0; index < mWave.length; index ++) {
mWave[index] = (int) (mAWave + mAWave * Math.sin(period * index));
}
mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mCacheBitmap);
canvas.setDrawFilter(mDrawFilter);
for (int index = 0; index < mWave.length; index++ ) {
canvas.drawLine(index, mWave[index], index, mHeight, mPaint);
}
mWave = null;
}
onDraw方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
long l = System.currentTimeMillis();
canvas.setDrawFilter(mDrawFilter);
mFirstOffset += mFirstWaveSpeed;
if(mFirstOffset > mWidth) {
mFirstOffset -= mWidth;
}
mSecondOffset += mSecondWaveSpeed;
if (mSecondOffset > mWidth) {
mSecondOffset -= mWidth;
}
canvas.drawBitmap(mCacheBitmap, mSecondOffset, 0, mPaint);
canvas.drawBitmap(mCacheBitmap, mSecondOffset - mWidth + 1, 0, mPaint);
canvas.drawBitmap(mCacheBitmap, mFirstOffset, 0, mPaint);
canvas.drawBitmap(mCacheBitmap, mFirstOffset - mWidth + 1, 0, mPaint);
invalidate();
long e = System.currentTimeMillis();
Log.e(TAG, "onDraw: " + (e - l));
}
查看在OnDraw中绘制耗费的时长,效率还不错,缩减了一半时长,但是发现居然有锯齿。。该设置的都设置了。。。
方法二:
用line绘制的有锯齿,那就用path画个没锯齿的,选择三阶贝赛尔曲线绘制
onSizeChange方法
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mCacheBitmap);
canvas.setDrawFilter(mDrawFilter);
Path path = new Path();
int A = TransformUnitUtil.dip2px(getContext(), mAWave);
path.reset();
path.moveTo(mWidth / 2, A);
path.quadTo(mWidth - mWidth /4, 2 * A, mWidth, A);
canvas.clipPath(path, Region.Op.XOR); //裁除交集部分,要在绘制canvas之前clip,如果绘制之后进行clip不会影响到已经画好的图形
//除此之外,cavas.clipPath不支持硬件加速,必须在AndroidManifest.xml中添加android:hardwareAccelerated="false",不然效果出不来
path.reset();
path.moveTo(0, A);
// path.cubicTo(mWidth / 4, 0, mWidth - mWidth / 4, 2 * A, mWidth, A);
path.quadTo(mWidth / 4, 0, mWidth / 2, A);
canvas.drawPath(path, mPaint);
canvas.drawRect(0, A, mWidth/2, mHeight, mPaint);
canvas.drawRect(mWidth / 2, A, mWidth, mHeight, mPaint);
mWave = null;
}
搞定!!!
完整代码:
package com.example.yinhua.myapplication.custome;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.example.yinhua.myapplication.utils.TransformUnitUtil;
/**
* Created by yinhua on 2017/3/18.
*/
public class WaveView extends View {
private static final String TAG = WaveView.class.getSimpleName();
private static final int WAVE_COLOR = 0xDD0000AA;
private int mWidth; //View宽
private int mHeight; //View高
private int mFirstWaveSpeed; //第一个水波纹的偏移速度
private int mSecondWaveSpeed; //第二个水波纹的偏移速度
private int mAWave = 10; //水波纹的振幅
private int[] mWave; //水波纹数组
private int mFirstOffset; //第一个水波纹偏移
private int mSecondOffset; //第一个水波纹偏移
private Paint mPaint;
private DrawFilter mDrawFilter;
private Bitmap mCacheBitmap;
public WaveView(Context context) {
this(context, null);
}
public WaveView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initSpeed();
initDrawTools();
}
/**
* 初始化偏移速度
*/
private void initSpeed() {
mFirstWaveSpeed = TransformUnitUtil.dip2px(getContext(), 4);
mSecondWaveSpeed = TransformUnitUtil.dip2px(getContext(), 5);
}
/**
* 初始化绘图工具
*/
private void initDrawTools() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(WAVE_COLOR);
mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
// mWave = new int[mWidth];
// float period = (float) (2 * Math.PI / mWidth);
// for (int index = 0; index < mWave.length; index ++) {
// mWave[index] = (int) (mAWave + mAWave * Math.sin(period * index));
// }
mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mCacheBitmap);
canvas.setDrawFilter(mDrawFilter);
// for (int index = 0; index < mWave.length; index++ ) {
// canvas.drawLine(index, mWave[index], index, mHeight, mPaint);
// }
Path path = new Path();
int A = TransformUnitUtil.dip2px(getContext(), mAWave);
path.reset();
path.moveTo(mWidth / 2, A);
path.quadTo(mWidth - mWidth /4, 2 * A, mWidth, A);
canvas.clipPath(path, Region.Op.XOR); //裁除交集部分,要在绘制canvas之前clip,如果绘制之后进行clip不会影响到已经画好的图形
//除此之外,cavas.clipPath不支持硬件加速,必须在AndroidManifest.xml中添加android:hardwareAccelerated="false",不然效果出不来
path.reset();
path.moveTo(0, A);
// path.cubicTo(mWidth / 4, 0, mWidth - mWidth / 4, 2 * A, mWidth, A);
path.quadTo(mWidth / 4, 0, mWidth / 2, A);
canvas.drawPath(path, mPaint);
canvas.drawRect(0, A, mWidth/2, mHeight, mPaint);
canvas.drawRect(mWidth / 2, A, mWidth, mHeight, mPaint);
mWave = null;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
long l = System.currentTimeMillis();
// Log.e(TAG, "onDraw: " + l);
canvas.setDrawFilter(mDrawFilter);
mFirstOffset += mFirstWaveSpeed;
if(mFirstOffset > mWidth) {
mFirstOffset -= mWidth;
}
mSecondOffset += mSecondWaveSpeed;
if (mSecondOffset > mWidth) {
mSecondOffset -= mWidth;
}
canvas.drawBitmap(mCacheBitmap, mSecondOffset, 0, mPaint);
canvas.drawBitmap(mCacheBitmap, mSecondOffset - mWidth + 1, 0, mPaint);
canvas.drawBitmap(mCacheBitmap, mFirstOffset, 0, mPaint);
canvas.drawBitmap(mCacheBitmap, mFirstOffset - mWidth + 1, 0, mPaint);
invalidate(); //考虑延迟几秒之后再刷新绘制
long e = System.currentTimeMillis();
Log.e(TAG, "onDraw: " + (e - l));
}
}