http://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; /** * * http://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代替 * http://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的各种效果:
完整源码:点击下载
出处:http://www.havenliu.com/other/689.html,谢谢!
时间: 2024-09-21 17:28:17