Android在自定義View(SurfaceView)中實現進度條Progress
https://www.havenliu.com/java/689.html
Android本身帶有Progress控件。可以在布局中靈活使用,但如果是在自定義的View或者SurfaceView中使用,就需要自己實現,其實不難,隻要熟悉了android的PorterDuff,就能利用PorterDuff的遮罩效果方便的實現進度條。
PorterDuff.Mode的靈活使用可以實現很多強大的功能,比如以前比較流行的美女擦玻璃,在屏幕上用手指繪圖或橡皮檫等功能。
下麵是源碼,老規矩,完整源碼中文章末尾下載。
先上一張效果圖:
Main.java,這是個Activity,地球人都看的懂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
package com.havenliu.progressdemo; import android.app.Activity; import android.os.Bundle; import android.view.Display; import android.view.Window; import android.view.WindowManager; /** * * https://www.havenliu.com/other/689.html * @author HavenLiu * */ public class Main extends Activity { public static int screen_width;// 屏幕的寬度 public static int screen_height;// 屏幕的高度 //圖片資源根據遊戲屏幕的縮放比例 public static float zoomRate; public static boolean isRun; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 全屏顯示窗口 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); isRun = true; Display display = getWindowManager().getDefaultDisplay(); screen_width = display.getWidth(); screen_height = display.getHeight(); zoomRate = getZoomRate(); setContentView(new MyView(this)); } /** * 計算圖片的縮放比例,這要是為了讓圖片能自適應屏幕大小 * * @return */ private float getZoomRate() { float rate = 1f; float rate_width = screen_width / 44f;// 圖片資源的寬度為44px float rate_height = screen_height / 547f;// 圖片資源的高度為547px rate = Math.min(rate_width, rate_height); return rate; } @Override protected void onDestroy() { super.onDestroy(); isRun = false; } } |
MyView.java:是一個自定義View,為了簡單,這沒有使用SurfaceView,其實是一樣的。裏麵實現了對分辨率的自適應,可以在不同分辨率下保證progress的精準。
?Download MyView.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package com.havenliu.progressdemo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.view.View; /** * 自定義View,也可以用SurfaceView代替 * https://www.havenliu.com/other/689.html * @author HavenLiu * * */ public class MyView extends View implements Runnable { // 遊戲總時間,單位:秒 public static final int TOTALTIME = 30; // 刷新頻率:毫秒 public static final int REFRESH = 30; private Bitmap img_progress; private Bitmap img_progress_bg; // 屏幕每次刷新,progressBar應減去的長度 private float step; private Paint paint; // progressBar的中長度 private float progress; public MyView(Context context) { super(context); paint = new Paint(); paint.setDither(true); initBitmap(); initProgress(); new Thread(this).start(); } /** * 預加載圖片圖片資源,並根據屏幕大小等比縮放 */ private void initBitmap() { Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.timebar); Matrix matrix = new Matrix(); matrix.postScale(Main.zoomRate, Main.zoomRate); img_progress = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); Bitmap bitmap_bg = BitmapFactory.decodeResource(getResources(), R.drawable.timebar_bg); img_progress_bg = Bitmap.createBitmap(bitmap_bg, 0, 0, bitmap_bg.getWidth(), bitmap_bg.getHeight(), matrix, true); } /** * 初始化progressBar相關參數 */ private void initProgress() { int _totalTime = TOTALTIME * 1000; int refreshTimes = _totalTime / REFRESH; progress = 547.0f * Main.zoomRate; step = progress / refreshTimes;// 547為滾動條的高度 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawARGB(255, 157, 157, 157); // 居中 canvas.drawBitmap(img_progress, Main.screen_width / 2 - img_progress.getWidth() / 2, 0, null);// 背景條:藍色 int rc = canvas.saveLayer(Main.screen_width / 2 - img_progress.getWidth() / 2, img_progress.getHeight() - progress, Main.screen_width / 2 + img_progress.getWidth() / 2, img_progress.getHeight(), null, Canvas.ALL_SAVE_FLAG); paint.setFilterBitmap(false); canvas.drawRect(Main.screen_width / 2 - img_progress.getWidth() / 2, 0, Main.screen_width / 2 + img_progress.getWidth() / 2, img_progress.getHeight(), paint); //Xfermode的類型很重要,不同的Mode有不同的效果。具體可以參考後麵的圖片 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(img_progress_bg, Main.screen_width / 2 - img_progress.getWidth() / 2, 0, paint); paint.setXfermode(null); canvas.restoreToCount(rc); } @Override public void run() { while (Main.isRun) { postInvalidate(); if (progress <= 0) { // Game Over..... // do something...... // Log.i("", "Game over.........you lost!"); } else { progress -= step; } try { Thread.sleep(REFRESH); } catch (InterruptedException e) { e.printStackTrace(); } } } } |
PorterDuff.Mode的各種效果:
完整源碼:點擊下載
出處:https://www.havenliu.com/other/689.html,謝謝!
最後更新:2017-04-03 18:51:45