背景:因系统的ProgressBar设置图片时,如果图片不够大,而在大分辨率的手机上时会出现无法填充满,所以自己写一个,既修复该问题,又可方便拓展,所以抛砖引玉
功能介绍:横向进度条,分为背景与封面两层,封面与背景均支持圆角矩形、渐变、图片。
效果图:
(上面仿微博加载图片进度条在另一篇博文中:http://blog.csdn.net/fy993912_chris/article/details/77370206)
<com.example.work.myapplication.widget.ProgressBarHorizontal android:layout_width="match_parent" android:layout_height="25dp" app:pbhBgColorEnd="#01978a" app:pbhBgColorStart="#00a2e9" app:pbhBgRadius="15dp" app:pbhBgSrc="@mipmap/ic_health_bg_2" app:pbhCoverColorEnd="@color/colorAccent" app:pbhCoverColorStart="@color/colorPrimary" app:pbhCoverSrc="@mipmap/ic_life_bg" app:pbhProgress="50" app:pbhScaleType="match_parent" /> <com.example.work.myapplication.widget.ProgressBarHorizontal android:layout_width="match_parent" android:layout_height="25dp" android:layout_marginTop="5dp" app:pbhBgColorEnd="#01978a" app:pbhBgColorStart="#00a2e9" app:pbhBgRadius="15dp" app:pbhCoverColorEnd="@color/colorAccent" app:pbhCoverColorStart="@color/colorPrimary" app:pbhCoverSrc="@mipmap/ic_life_bg" app:pbhProgress="50" app:pbhScaleType="match_parent" /> <com.example.work.myapplication.widget.ProgressBarHorizontal android:layout_width="match_parent" android:layout_height="25dp" android:layout_marginTop="5dp" app:pbhBgColorEnd="#01978a" app:pbhBgColorStart="#00a2e9" app:pbhBgLbRadius="14dp" app:pbhBgLtRadius="14dp" app:pbhBgRbRadius="0dp" app:pbhBgRtRadius="0dp" app:pbhCoverColorEnd="@color/colorAccent" app:pbhCoverColorStart="@color/colorPrimary" app:pbhCoverLbRadius="14dp" app:pbhCoverLtRadius="14dp" app:pbhCoverRbRadius="0dp" app:pbhCoverRtRadius="0dp" app:pbhProgress="50" app:pbhScaleType="match_parent" />
使用方法非常简单,只需要在xml中配置对应属性便可实时预览效果
需要注意的是控件会有一个优先级别显示:
依次为:
图片->圆角矩形
设置圆角时,radius会优于rt、rb、lt、lb属性
scaleType:
match_content:以控件大小为准
wrap_content:以封面图片大小为准
具体可以查看代码或者配置xml进行查看,这里就不多说啦。
以下是代码--------------------------------------------------------------------------------------------------
clss类文件源码
/** * Created by work on 2017/8/8. * 横向进度条 * * @author chris zou * @mail [email protected] */ public class ProgressBarHorizontal extends View { public float maxProgress = 100; /*背景*/ Bitmap bgBitmap; int bgColorStart; int bgColorEnd; int[] bgColors; int bgRadius; int bgLtRadius; int bgLbRadius; int bgRbRadius; int bgRtRadius; Paint bgPaint; /*end*/ /*图片*/ Bitmap coverBitmap; int coverColorStart; int coverColorEnd; int[] coverColors; int coverRadius; int coverLtRadius; int coverLbRadius; int coverRtRadius; int coverRbRadius; Paint coverPaint; /*end*/ int w, h; int compareMinSize;//高与宽较小那个 int scaleType; float progress; public ProgressBarHorizontal(Context context) { this(context, null); } public ProgressBarHorizontal(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public ProgressBarHorizontal(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context.obtainStyledAttributes(attrs, R.styleable.ProgressBarHorizontal)); } public void init(TypedArray typedArray) { setupParams(typedArray); setupPaint(); } /** * 设置参数 */ public void setupParams(TypedArray typedArray) { bgColorStart = typedArray.getColor(R.styleable.ProgressBarHorizontal_pbhBgColorStart, Color.DKGRAY); bgColorEnd = typedArray.getColor(R.styleable.ProgressBarHorizontal_pbhBgColorEnd, bgColorStart); bgColors = new int[]{bgColorStart, bgColorEnd}; bgRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhBgRadius, 0); bgLtRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhBgLtRadius, 0); bgLbRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhBgLbRadius, 0); bgRbRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhBgRbRadius, 0); bgRtRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhBgRtRadius, 0); Drawable coverDrawable = typedArray.getDrawable(R.styleable.ProgressBarHorizontal_pbhBgSrc); bgBitmap = coverDrawable != null ? ((BitmapDrawable) coverDrawable).getBitmap() : null; coverColorStart = typedArray.getColor(R.styleable.ProgressBarHorizontal_pbhCoverColorStart, Color.GRAY); coverColorEnd = typedArray.getColor(R.styleable.ProgressBarHorizontal_pbhCoverColorEnd, coverColorStart); coverColors = new int[]{coverColorStart, coverColorEnd}; coverRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhCoverRadius, 0); coverLtRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhCoverLtRadius, 0); coverLbRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhCoverLbRadius, 0); coverRbRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhCoverRbRadius, 0); coverRtRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBarHorizontal_pbhCoverRtRadius, 0); Drawable bottomDrawable = typedArray.getDrawable(R.styleable.ProgressBarHorizontal_pbhCoverSrc); coverBitmap = bottomDrawable != null ? ((BitmapDrawable) bottomDrawable).getBitmap() : null; progress = typedArray.getInteger(R.styleable.ProgressBarHorizontal_pbhProgress, 0); scaleType = typedArray.getInteger(R.styleable.ProgressBarHorizontal_pbhScaleType, 0); } public void setupPaint() { bgPaint = new Paint(); bgPaint.setColor(bgColorStart); bgPaint.setStyle(Paint.Style.FILL); bgPaint.setAntiAlias(true); coverPaint = new Paint(); coverPaint.setColor(coverColorStart); coverPaint.setStyle(Paint.Style.FILL); coverPaint.setAntiAlias(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (scaleType == 0) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } else { if (coverBitmap == null) { throw new NullPointerException("wrap_content must set image res"); } setMeasuredDimension(coverBitmap.getWidth(), coverBitmap.getHeight()); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.w = w; this.h = h; compareMinSize = w > h ? h : w; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //bg bgPaint.setShader(new LinearGradient(0, h / 2, w, h / 2, bgColors, null, Shader.TileMode.MIRROR)); if (bgBitmap != null) { canvas.drawBitmap(bgBitmap, null, new RectF(0, 0, w, h), null); } else if (bgRadius != 0) { RectF bgRec = new RectF(0, 0, w, h); canvas.drawRoundRect(bgRec, bgRadius, bgRadius, bgPaint); } else { drawPath(canvas, bgLtRadius, bgLbRadius, bgRbRadius, bgRtRadius, w, bgPaint); } //cover coverPaint.setShader(new LinearGradient(0, h / 2, w, h / 2, coverColors, null, Shader.TileMode.MIRROR)); float progressWidth = w - w * ((maxProgress - progress) / maxProgress); if (coverBitmap != null) { RectF imgRect = new RectF(0, 0, progressWidth, h); Rect srcRect = new Rect(0, 0, (int) progressWidth, h); canvas.drawBitmap(coverBitmap, srcRect, imgRect, null); } else if (coverRadius != 0) { RectF coverRec = new RectF(0, 0, progressWidth, h); canvas.drawRoundRect(coverRec, coverRadius, coverRadius, coverPaint); } else { drawPath(canvas, coverLtRadius, coverLbRadius, coverRbRadius, coverRtRadius, progressWidth, coverPaint); } } /** * 做一阶贝塞尔曲线 * * @param canvas * @param lt * @param lb * @param rb * @param rt * @param w * @param paint */ private void drawPath(Canvas canvas, int lt, int lb, int rb, int rt, float w, Paint paint) { //左上角,逆时针开始 Path path = new Path(); //左上 path.moveTo(lt, 0); path.quadTo(0, 0, 0, lt); //左下 path.lineTo(0, h - lb); path.quadTo(0, h, lb, h); //右下 path.lineTo(w - rb, h); path.quadTo(w, h, w, h - rb); //右上 path.lineTo(w, rt); path.quadTo(w, 0, w - rt, 0); //回到左上角 path.lineTo(lt, 0); canvas.drawPath(path, paint); } /** * @param progress 0-100 */ public void setProgress(float progress) { if (progress > maxProgress) { progress = maxProgress; } this.progress = progress; postInvalidate(); } public void setBgColors(int[] colors) { this.bgColors = colors; } public void setCoverColors(int[] colors) { this.coverColors = colors; } }
attrs属性内容
<declare-styleable name="ProgressBarHorizontal"> <attr name="pbhBgSrc" format="reference" /> <attr name="pbhBgColorStart" format="color" /> <attr name="pbhBgColorEnd" format="color" /> <attr name="pbhBgRadius" format="dimension" /> <attr name="pbhBgLtRadius" format="dimension" /> <attr name="pbhBgLbRadius" format="dimension" /> <attr name="pbhBgRbRadius" format="dimension" /> <attr name="pbhBgRtRadius" format="dimension" /> <attr name="pbhCoverSrc" format="reference" /> <attr name="pbhCoverColorStart" format="color" /> <attr name="pbhCoverColorEnd" format="color" /> <attr name="pbhCoverRadius" format="dimension" /> <attr name="pbhCoverLtRadius" format="dimension" /> <attr name="pbhCoverLbRadius" format="dimension" /> <attr name="pbhCoverRbRadius" format="dimension" /> <attr name="pbhCoverRtRadius" format="dimension" /> <attr name="pbhProgress" format="integer" /> <attr name="pbhScaleType"> <enum name="match_parent" value="0" /> <enum name="wrap_content" value="1" /> </attr> </declare-styleable>
将源码拷贝到自己的工程就可以啦。