用系統的Progressbar,設置圖片drawable作為進度條會出現圖片長度不好控制,容易被截斷,或者變形的問題。而我有個需求,使用圖片背景,和圖片進度,而且在進度條頭部有個閃光點效果。
如下圖:
找了兩個小時,國內外,百度,github搜遍了,全網都沒有找到一個現成的。
最后只好自己寫一個。本來我用自己代碼寫的用顏色值的進度條,很容易就實現了。
產品要用設計師的圖片。誰知道啊,這么個小功能卻這么麻煩,為這么個進度條的功能加班到晚上11點。
package com.alisajidapps.watermarkpdfss.view;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.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;import com.alisajidapps.watermarkpdfss.R;public class CustomProgressBar extends View {private Paint paint;private Bitmap progressBarImage;private Bitmap backgroundImage;private Bitmap progressPointerBitmap;private Rect srcRect;private Rect dstRect;private int progress;//手機寬度private int screenWidth;private int progressWidth;private int progressHeight;//縮放后的進度條寬度private int progressBarWidthNew;private Rect pointerRect;private Rect pointerDstRect;public CustomProgressBar(Context context) {super(context);init();}public CustomProgressBar(Context context, AttributeSet attrs) {super(context, attrs);init();}public CustomProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {paint = new Paint();progressBarImage = BitmapFactory.decodeResource(getResources(), R.drawable.update_progress); // 你的進度條圖片資源backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.update_progress_bg); // 你的進度條圖片資源progressPointerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.update_progress_seek); // 你的進度條圖片資源DisplayMetrics displayMetrics = getResources().getDisplayMetrics();screenWidth = displayMetrics.widthPixels;scale = (float) (screenWidth*0.7/backgroundImage.getWidth());progressWidth = progressBarImage.getWidth();progressHeight = progressBarImage.getHeight();progressBarWidthNew = (int) (progressBarImage.getWidth()*scale);srcRect = new Rect();dstRect = new Rect();backRect=new Rect();backDstRect=new Rect();pointerRect = new Rect();pointerDstRect = new Rect();progress =10;}public void setProgress(int progress) {this.progress = progress;invalidate(); // 重繪視圖}Rect backRect;Rect backDstRect;float scale;@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Log.e("xxx","scrrenWidth:"+screenWidth);//第一步,畫背景backRect.left =0;backRect.top = 0;backRect.right = backgroundImage.getWidth();backRect.bottom = backgroundImage.getHeight();Log.e("xxx",scale+"");Log.e("xxx","backgroundImageWidth:"+backgroundImage.getWidth()+"");backDstRect.top =20;backDstRect.left = (int) (screenWidth/2 - (backgroundImage.getWidth() * scale/2));backDstRect.right = (int) (screenWidth/2 + (backgroundImage.getWidth() * scale/2));backDstRect.bottom = (int) (backgroundImage.getHeight() * scale)+20;// 繪制縮放后的位圖,dstRect縮放后,畫進去的圖片就是縮放的。canvas.drawBitmap(backgroundImage, backRect, backDstRect, paint);//第二步,畫進度條srcRect.left = 0;srcRect.top = 0;srcRect.right = progressWidth;srcRect.bottom = progressHeight;Log.e("xxx","progressWidth:"+progressWidth);Log.e("xxx","progressHeight:"+progressHeight);Log.e("xxx","progressbarWidth:"+progressBarImage.getWidth());progressWidth = (int) (progressBarWidthNew *progress / 100 ); // 假設進度是0到100//dstRect 等比例縮放了,畫進去的圖片就會等比例縮放dstRect.top =30;dstRect.left = (int) (screenWidth/2 - progressBarWidthNew/2);dstRect.right = dstRect.left+ progressWidth;dstRect.bottom = (int) (progressBarImage.getHeight() * scale+30);canvas.drawBitmap(progressBarImage, srcRect, dstRect, paint);Log.e("xxx","怎么沒有繪制:"+progressWidth);//第三步,畫進度條前面的指針效果pointerRect.left = 0;pointerRect.top = 0;pointerRect.right = progressPointerBitmap.getWidth();pointerRect.bottom = progressPointerBitmap.getHeight();pointerDstRect.left = dstRect.right-15;pointerDstRect.top = 0;pointerDstRect.right = (int) (dstRect.right+ progressPointerBitmap.getWidth()*scale-15);pointerDstRect.bottom = (int) (progressPointerBitmap.getHeight()*scale);canvas.drawBitmap(progressPointerBitmap,pointerRect,pointerDstRect,paint);}
}
使用時只需要調用setProgressBar就行。
上圖就是代碼實現的效果。
?
知識總結:
1,基本的繪制圖片方法
drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
參數://Bitmap:圖片對象,left:偏移左邊的位置,top: 偏移頂部的位置
?
2, drawBitmap( Bitmap bitmap, Rect src, Rect dst, Paint paint);
?
這里由2個Rect,第一個Rect --src 代表要裁剪的bitmap的區域,如傳null,表示需要繪制整個圖片,
?
第二個Rect ---det表示需要將bitmap,繪制在屏幕上的位置,不可為空,并且大于src則把src的裁截區放大,小于src則把src的裁截區縮小。
?
?Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.ic_logo);
? ? ? ? //繪制方法1:---原圖,制作偏移
? ? ? ? canvas.drawBitmap(bitmap,100,100,mPaint);//將圖片從(0,0)位置向左偏移100,向右偏移100
?
? ? ? ? Rect srcRect = new Rect(0,0,bitmap.getWidth()/2,bitmap.getHeight()/2);//截取圖片左上1/4的區域
?
? ? ? ? Rect dstRect = new Rect(500,500,800,800);//圖片需要繪制的矩形區域
? ? ? ? //繪制方法2:--先裁剪再展示
? ? ? ? canvas.drawBitmap(bitmap,srcRect,dstRect, mPaint);