Android在自定义View(SurfaceView)中实现进度条Progress

来源:互联网 发布:杀破狼 js 无损百度云 编辑:程序博客网 时间:2024/05/01 00:47

ndroid本身带有Progress控件。可以在布局中灵活使用,但如果是在自定义的View或者SurfaceView中使用,就需要自己实现,其实不难,只要熟悉了android的PorterDuff,就能利用PorterDuff的遮罩效果方便的实现进度条。

PorterDuff.Mode的灵活使用可以实现很多强大的功能,比如以前比较流行的美女擦玻璃,在屏幕上用手指绘图或橡皮檫等功能。

下面是源码,老规矩,完整源码中文章末尾下载。

先上一张效果图:
Progress效果

Main.java,这是个Activity,地球人都看的懂

?Download Main.java
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
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; @Overridepublic 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;// 图片资源的宽度为44pxfloat rate_height = screen_height / 547f;// 图片资源的高度为547pxrate = Math.min(rate_width, rate_height);return rate;} @Overrideprotected void onDestroy() {super.onDestroy();isRun = false;}}

MyView.java:是一个自定义View,为了简单,这没有使用SurfaceView,其实是一样的。里面实现了对分辨率的自适应,可以在不同分辨率下保证progress的精准。

?Download MyView.java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
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为滚动条的高度} @Overrideprotected 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);} @Overridepublic 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的各种效果:
PorterDuff.Mode效果

完整源码:点击下载

http://www.havenliu.com/java/689.html