您的位置:首页 > 移动开发 > Android开发

自定义View-圆球进度的实现(仿360波浪进度)

2017-06-19 18:01 786 查看
一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域。

今天我这用图片bitmap的方式,大概的方法原理是:

(1)首先用clipPath裁剪园区域,

(2)然后用4张图来不断绘制到画布上,再用偏移量来控制移动的速度,从而形成波浪动态效果。

(3)有一点需要注意的是,裁剪圆的时候用到的clipPath这个方法,在android 4.1,和4.2等某些系统上,裁剪出来不是圆,而是矩形,针对这些系统 需要在manifest.xml文件的activity中将硬件加速关掉,因为默认是开启的。即添加这个:android:hardwareAccelerated="false"

(1)自定义波浪View的实现:

/**
*
* @author hjy
* 用波浪效果实现横滚动画
*/
public class SinkingView extends FrameLayout {
private static final int DEFAULT_TEXTCOLOT = 0xFFFFFFFF;

private static final int DEFAULT_TEXTSIZE = 25;

private float mPercent;

private Paint mPaint = new Paint();

private Bitmap mBitmap;

private Bitmap mScaledBitmap;

private float mLeft;

private int mSpeed = 15;

private int mRepeatCount = 0;

private Status mFlag = Status.NONE;

private int mTextColor = DEFAULT_TEXTCOLOT;

private int mTextSize = DEFAULT_TEXTSIZE;

public SinkingView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void setTextColor(int color) {
mTextColor = color;
}

public void setTextSize(int size) {
mTextSize = size;
}

public void setPercent(float percent) {
mFlag = Status.RUNNING;
mPercent = percent;
postInvalidate();

}

public void setStatus(Status status) {
mFlag = status;
}

public void clear() {
mFlag = Status.NONE;
if (mScaledBitmap != null) {
mScaledBitmap.recycle();
mScaledBitmap = null;
}

if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
}

@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
int width = getWidth();
int height = getHeight();

//裁剪成圆区域
Path path = new Path();
canvas.save();
path.reset();
canvas.clipPath(path);
path.addCircle(width / 2, height / 2, width / 2, Direction.CCW);
canvas.clipPath(path, Op.REPLACE);//UNION REPLACE REVERSE_DIFFERENCE XOR

if (mFlag == Status.RUNNING) {
if (mScaledBitmap == null) {
mBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.wave4);
mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth(), getHeight(), false);
mBitmap.recycle();
mBitmap = null;
mRepeatCount = (int) Math.ceil(getWidth() / mScaledBitmap.getWidth() + 0.5) + 1;
}
for (int idx = 0; idx < mRepeatCount; idx++) {
canvas.drawBitmap(mScaledBitmap, mLeft + (idx - 1) * mScaledBitmap.getWidth(), (1-mPercent) * getHeight(), null);
}
//            String str = (int) (mPercent * 100) + "%";
//            mPaint.setColor(mTextColor);
//            mPaint.setTextSize(mTextSize);
//            mPaint.setStyle(Style.FILL);
//            canvas.drawText(str, (getWidth() - mPaint.measureText(str)) / 2, getHeight() / 2 + mTextSize / 2, mPaint);

mLeft += mSpeed;
if (mLeft >= mScaledBitmap.getWidth())
mLeft = 0;
// 绘制外圆环
//            mPaint.setStyle(Paint.Style.STROKE);
//            mPaint.setStrokeWidth(1);
//            mPaint.setAntiAlias(true);
//            mPaint.setColor(Color.parseColor("#03f0ee"));
//            canvas.drawCircle(width / 2, height / 2, width / 2 - 2, mPaint);

postInvalidateDelayed(20);
}
canvas.restore();

}

public enum Status {
RUNNING, NONE
}
}

(2)布局文件的实现:


(3)如何使用自定义波浪View:

private SinkingView sv_menu_pitchs = (SinkingView) findViewById(R.id.sv_menu_pitchs);
private float percent = 0;
percent = 1.50f;
sv_menu_pitchs.setPercent(percent);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息