效果:
用到图片下载:
自定义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>
时间: 2024-08-29 08:13:18