自定义View_撸一个带纹理效果的进度条

最近遇到了一个这样的设计图,猛地一看竟然不知道如何下手,一开始想到了progressBar改下样式,但是貌似不太好改,后来请教了一下大佬有了一些思路。先来看看样式:


自定义View_撸一个带纹理效果的进度条_第1张图片
QQ20180917-0.jpg

好吧,先分析一下,整个就是一个view,如何显示里面的那个类似大于号的纹理图案是最核心的地方,这里我使用了小图片资源转化为bitmap然后绘制即可。

过程

1.获取Bitmap

mBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_time_line);

2.通过计算给Bitmap设置宽高(我用的128*128的图片,宽高一致)

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmapSize = h - getPaddingBottom() - getPaddingTop();
    mBitmap = resizeImage(mBitmap, mBitmapSize, mBitmapSize);
}


/**
 * 缩放bitmap
 *
 * @param bitmap
 * @param w
 * @param h
 * @return
 */
public Bitmap resizeImage(Bitmap bitmap, int w, int h) {
    Bitmap BitmapOrg = bitmap;
    int width = BitmapOrg.getWidth();
    int height = BitmapOrg.getHeight();
    int newWidth = w;
    int newHeight = h;
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
            height, matrix, true);
    return resizedBitmap;
}

3.计算需要绘制的数量,然后绘制

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int count = ((getWidth() - getPaddingLeft() - getPaddingRight()) / mBitmapSize);
    /**
     * 这里如果有剩余空间不足够绘制一个完整Bitmap的情况时,我们就再多绘制一个
     */
    if ((getWidth() - getPaddingLeft() - getPaddingRight()) % mBitmapSize > 0) {
        count += 1;
    }
    for (int i = 0; i < count; i++) {
        canvas.drawBitmap(mBitmap, i * mBitmapSize + getPaddingLeft(), getPaddingTop(), mPaintPic);
    }
}

OK,大功告成。这里只是提供一个实现思路,没有考虑太多的扩展性,如果需要的自己略微修改即可。

完整代码

public class CustomTimeLineView extends View {

    private Context mContext;

    private Paint mPaintPic;
    private Bitmap mBitmap;

    private int mBitmapSize;//Bitmap的高度和宽度

    public CustomTimeLineView(Context context) {
        this(context, null);
    }

    public CustomTimeLineView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomTimeLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;

        mPaintPic = new Paint();
        mPaintPic.setAntiAlias(true);

        mBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_time_line);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmapSize = h - getPaddingBottom() - getPaddingTop();
        mBitmap = resizeImage(mBitmap, mBitmapSize, mBitmapSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int count = ((getWidth() - getPaddingLeft() - getPaddingRight()) / mBitmapSize);
        /**
         * 这里如果有剩余空间不足够绘制一个完整Bitmap的情况时,我们就再多绘制一个
         */
        if ((getWidth() - getPaddingLeft() - getPaddingRight()) % mBitmapSize > 0) {
            count += 1;
        }
        for (int i = 0; i < count; i++) {
            canvas.drawBitmap(mBitmap, i * mBitmapSize + getPaddingLeft(), getPaddingTop(), mPaintPic);
        }
    }


    /**
     * 缩放bitmap
     *
     * @param bitmap
     * @param w
     * @param h
     * @return
     */
    public Bitmap resizeImage(Bitmap bitmap, int w, int h) {
        Bitmap BitmapOrg = bitmap;
        int width = BitmapOrg.getWidth();
        int height = BitmapOrg.getHeight();
        int newWidth = w;
        int newHeight = h;

        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
                height, matrix, true);
        return resizedBitmap;
    }

}

代码很简单,就不上传github了。

你可能感兴趣的:(自定义View_撸一个带纹理效果的进度条)