用系统的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;
@Override
protected 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);