思路:
1.首先用clipPath裁剪圆形区域,
2.将Bitmap不断绘制到Canvas上,再用偏移量来控制移动的速度,从而形成波浪动态效果。
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <com.jackie.sinkview.SinkView android:id="@+id/sink" android:layout_width="400dp" android:layout_height="400dp" android:layout_centerInParent="true" > </com.jackie.sinkview.SinkView> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:orientation="horizontal" > <Button android:id="@+id/check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="体验" /> </LinearLayout> </RelativeLayout>SinkView.java
package com.jackie.sinkview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Region; import android.util.AttributeSet; import android.widget.FrameLayout; /** * 水波浪球形进度条 */ public class SinkView extends FrameLayout { private Bitmap mBitmap, mScaleBitmap; private Paint mPaint = new Paint(); private int mRepeatCount; private int mSpeed = 15; private float mLeft, mPercent; private static final int mTextColor = 0xFFFFFFFF; private static final int mTextSize = 250; public SinkView(Context context, AttributeSet attrs) { super(context, attrs); } public void setPercent(float percent) { mPercent = percent; postInvalidate(); } @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, Path.Direction.CCW); canvas.clipPath(path, Region.Op.REPLACE); if (mScaleBitmap == null) { mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sink); mScaleBitmap = Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth(), getHeight(), false); mBitmap.recycle(); mBitmap = null; mRepeatCount = (int) Math.ceil(getWidth() / mScaleBitmap.getWidth() + 0.5) + 1; } for (int i = 0; i < mRepeatCount; i++) { canvas.drawBitmap(mScaleBitmap, mLeft + (i - 1) * mScaleBitmap.getWidth(), (1 - mPercent) * getHeight(), null); } String text = (int) (mPercent * 100) + "%"; mPaint.setColor(mTextColor); mPaint.setTextSize(mTextSize); mPaint.setStyle(Paint.Style.FILL); canvas.drawText(text, (getWidth() - mPaint.measureText(text)) / 2, getHeight() / 2 + mTextSize / 2, mPaint); mLeft += mSpeed; if (mLeft >= mScaleBitmap.getWidth()) { mLeft = 0; } //绘制外圆环 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(4); mPaint.setAntiAlias(true); mPaint.setColor(Color.rgb(33, 211, 39)); canvas.drawCircle(width / 2, height / 2, width / 2 - 2, mPaint); postInvalidateDelayed(20); canvas.restore(); } }MainActivity.java
package com.jackie.sinkview; import android.app.Activity; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity { private SinkView mSinkView; private float mPercent; private Thread mThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSinkView = (SinkView) findViewById(R.id.sink); findViewById(R.id.check).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { check(); } }); mPercent = 0.3f; mSinkView.setPercent(mPercent); } private void check() { mThread = new Thread(new Runnable() { @Override public void run() { mPercent = 0; while (mPercent <= 1) { mSinkView.setPercent(mPercent); mPercent += 0.01f; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } //当进度条到100%时,重置初始百分比 mPercent = 0.3f; mSinkView.setPercent(mPercent); } }); mThread.start(); } }效果图如下: