Android 自定义图片进度条

用系统的Progressbar,设置图片drawable作为进度条会出现图片长度不好控制,容易被截断,或者变形的问题。而我有个需求,使用图片背景,和图片进度,而且在进度条头部有个闪光点效果。

如下图:

1605e545fb19408284eb6b6bda03fd28.jpeg

找了两个小时,国内外,百度,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);

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值