Canvas绘制水波进度加载

效果:

用到图片下载:

自定义View:

  1 package com.czm.mysinkingview;
  2 
  3 import android.content.Context;
  4 import android.graphics.Bitmap;
  5 import android.graphics.BitmapFactory;
  6 import android.graphics.Canvas;
  7 import android.graphics.Color;
  8 import android.graphics.Paint;
  9 import android.graphics.Paint.Style;
 10 import android.graphics.Path;
 11 import android.graphics.Path.Direction;
 12 import android.graphics.Region.Op;
 13 import android.util.AttributeSet;
 14 import android.widget.FrameLayout;
 15 /**
 16  * 水波浪球形进度View
 17  * @author caizhiming
 18  *
 19  */
 20 public class SinkingView extends FrameLayout {
 21     private static final int DEFAULT_TEXTCOLOT = 0xFFFF0000;
 22 
 23     private static final int DEFAULT_TEXTSIZE =40;
 24 
 25     private float mPercent;
 26 
 27     private Paint mPaint = new Paint();
 28 
 29     private Bitmap mBitmap;
 30 
 31     private Bitmap mScaledBitmap;
 32 
 33     private float mLeft;
 34 
 35     private int mSpeed = 15;
 36 
 37     private int mRepeatCount = 0;
 38 
 39     private Status mFlag = Status.NONE;
 40 
 41     private int mTextColor = DEFAULT_TEXTCOLOT;
 42 
 43     private int mTextSize = DEFAULT_TEXTSIZE;
 44 
 45     public SinkingView(Context context, AttributeSet attrs) {
 46         super(context, attrs);
 47     }
 48 
 49     public void setTextColor(int color) {
 50         mTextColor = color;
 51     }
 52 
 53     public void setTextSize(int size) {
 54         mTextSize = size;
 55     }
 56 
 57     public void setPercent(float percent) {
 58         mFlag = Status.RUNNING;
 59         mPercent = percent;
 60         postInvalidate();
 61 
 62     }
 63 
 64     public void setStatus(Status status) {
 65         mFlag = status;
 66     }
 67 
 68     public void clear() {
 69         mFlag = Status.NONE;
 70         if (mScaledBitmap != null) {
 71             mScaledBitmap.recycle();
 72             mScaledBitmap = null;
 73         }
 74 
 75         if (mBitmap != null) {
 76             mBitmap.recycle();
 77             mBitmap = null;
 78         }
 79     }
 80 
 81     @Override
 82     protected void dispatchDraw(Canvas canvas) {
 83         super.dispatchDraw(canvas);
 84         int width = getWidth();
 85         int height = getHeight();
 86         
 87         //裁剪成圆区域
 88         Path path = new Path();
 89         canvas.save();
 90         path.reset();
 91         canvas.clipPath(path);
 92         path.addCircle(width / 2, height / 2, width / 2, Direction.CCW);
 93         canvas.clipPath(path, Op.REPLACE);
 94 
 95         if (mFlag == Status.RUNNING) {
 96             if (mScaledBitmap == null) {
 97                 mBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.wave2);
 98                 mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth(), getHeight(), false);
 99                 mBitmap.recycle();
100                 mBitmap = null;
101                 mRepeatCount = (int) Math.ceil(getWidth() / mScaledBitmap.getWidth() + 0.5) + 1;
102             }
103             for (int idx = 0; idx < mRepeatCount; idx++) {
104                 canvas.drawBitmap(mScaledBitmap, mLeft + (idx - 1) * mScaledBitmap.getWidth(), (1-mPercent) * getHeight(), null);
105             }
106             String str = (int) (mPercent * 100) + "%";
107             mPaint.setColor(mTextColor);
108             mPaint.setTextSize(mTextSize);
109             mPaint.setStyle(Style.FILL);
110             canvas.drawText(str, (getWidth() - mPaint.measureText(str)) / 2, getHeight() / 2 + mTextSize / 2, mPaint);
111 
112             mLeft += mSpeed;
113             if (mLeft >= mScaledBitmap.getWidth())
114                 mLeft = 0;
115             // 绘制外圆环
116             mPaint.setStyle(Paint.Style.STROKE);
117             mPaint.setStrokeWidth(4);
118             mPaint.setAntiAlias(true);
119             mPaint.setColor(Color.rgb(33, 211, 39));
120             canvas.drawCircle(width / 2, height / 2, width / 2 - 2, mPaint);
121 
122             postInvalidateDelayed(20);
123         }
124         canvas.restore();
125 
126     }
127 
128     public enum Status {
129         RUNNING, NONE
130     }
131 
132 }

 

 

调用:

 1 package com.czm.mysinkingview;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.View;
 6 import android.view.View.OnClickListener;
 7 
 8 /**
 9  * 测试用例页
10  * 
11  * @author caizhiming
12  */
13 public class MainActivity extends Activity {
14     private SinkingView mSinkingView;
15 
16     private float percent = 0;
17 
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22         mSinkingView = (SinkingView) findViewById(R.id.sinking);
23 
24         findViewById(R.id.btn_test).setOnClickListener(new OnClickListener() {
25             
26             @Override
27             public void onClick(View v) {
28                 // TODO Auto-generated method stub
29                 updateProgress();
30             }
31         });
32 
33         percent = 0.3f;
34         mSinkingView.setPercent(percent);
35     }
36 
37 
38     private void updateProgress() {
39         Thread thread = new Thread(new Runnable() {
40 
41             @Override
42             public void run() {
43 
44                 percent = 0;
45                 while (percent <= 1) {
46                     mSinkingView.setPercent(percent);
47                     percent += 0.01f;
48                     try {
49                         Thread.sleep(40);
50                     } catch (InterruptedException e) {
51                         e.printStackTrace();
52                     }
53                 }
54                 percent = 0.78f;
55                 if(percent>0.7&&percent<1){
56                     mSinkingView.setTextColor(0xFFFFFFFF);
57                 }
58                 mSinkingView.setPercent(percent);
59 //                 mSinkingView.clear();
60             }
61         });
62         thread.start();
63     }
64 
65 }

调用布局:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     
 6     tools:context=".MainActivity" >
 7 
 8     <com.czm.mysinkingview.SinkingView
 9         android:id="@+id/sinking"
10         android:layout_width="wrap_content"
11         android:layout_height="wrap_content" 
12         android:layout_centerInParent="true" >
13 
14         <ImageView
15             android:id="@+id/image"
16             android:layout_width="120dp"
17             android:layout_height="120dp"
18             android:src="@drawable/charming2" />
19     </com.czm.mysinkingview.SinkingView>
20 
21     <LinearLayout
22         android:layout_width="match_parent"
23         android:layout_height="wrap_content"
24         android:layout_alignParentBottom="true"
25         android:layout_centerHorizontal="true"
26         android:orientation="horizontal" >
27 
28         <Button
29             android:id="@+id/btn_test"
30             android:textColor="#ffffff"
31             android:background="#0000ff"
32             android:textSize="18sp"
33             android:layout_width="match_parent"
34             android:layout_height="50dp"
35             android:layout_margin="10dp"
36             android:text="更新" />
37         
38     </LinearLayout>
39 
40 </RelativeLayout>

清单文件配置:

 1  <activity
 2             android:name="com.czm.mysinkingview.MainActivity"
 3             android:label="@string/app_name"
 4             android:hardwareAccelerated="false"
 5              >
 6             <intent-filter>
 7                 <action android:name="android.intent.action.MAIN" />
 8 
 9                 <category android:name="android.intent.category.LAUNCHER" />
10             </intent-filter>
11         </activity>

 

posted @ 2016-08-31 14:35  全球顶尖骇客  阅读(3108)  评论(0编辑  收藏  举报