Android(安卓)自定义View--ProgressBar篇(三)
1、概述
1.1 目的 :
在我们的日常开发中,有很多Android UI界面上有一些特殊或者特别的控件与界面,是Android自带的控件所不能满足的,需要我们自己定制一些适合的控件来完成。
1.2 Android自定义View步骤 :
- 自定义属性;
- 选择和设置构造方法;
- 重写onMeasure()方法;
- 重写onDraw()方法;
- 重写onLayout()方法;
- 重写其他事件的方法(滑动监听等)。
2、代码实现
2.1 自定义属性:
我们通常将自定义属性定义在/values/attr.xml文件中(attr.xml文件需要自己创建)。
2.2 实现方法含义
1、在OnMeasure()方法中,测量自定义控件的大小,使自定义控件能够自适应布局各种各样的需求。
2、在OnDraw()方法中,利用哼哈二将(Canvas与Paint)来绘制要显示的内容。
3、在OnLayout()方法中来确定控件显示位置。
4、在OnTouchEvent()方法处理控件的触摸事件。、
[图片上传失败...(image-57f412-1538104403176)]
2.3 继承View实现代码
package com.fly.myview.progressbar;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.View;import com.fly.myview.R;import java.text.DecimalFormat;/** * * .----. * _.'__ `. * .--(Q)(OK)---/$\ * .' @ /$$$\ * : , $$$$$ * `-..__.-' _.-\$$$/ * `;_: `"' * .'"""""`. * /, FLY ,\ * // \\ * `-._______.-' * ___`. | .'___ * (______|______) *
* 包 名 : com.fly.myview.processbar * 作 者 : FLY * 创建时间 : 2017/9/26 * * 描述: 仿淘宝抢购进度条 */public class SaleProgressView extends View{ //商品总数 private int totalCount; //当前卖出数 private int currentCount; //动画需要的 private int progressCount; //售出比例 private float scale; //边框颜色 private int sideColor; //文字颜色 private int textColor; //边框粗细 private float sideWidth; //边框所在的矩形 private Paint sidePaint; //背景矩形 private RectF bgRectF; private float radius; private int width; private int height; private PorterDuffXfermode mPorterDuffXfermode; private Paint srcPaint; private Bitmap fgSrc; private Bitmap bgSrc; private String nearOverText; private String overText; private float textSize; private Paint textPaint; private float nearOverTextWidth; private float overTextWidth; private float baseLineY; private Bitmap bgBitmap; private boolean isNeedAnim; public SaleProgressView(Context context) { this(context,null); } public SaleProgressView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initAttrs(context,attrs); initPaint(); } private void initAttrs(Context context, AttributeSet attrs) { //存储资源数组的容器,通过obtaiStyledAttributes()方法创建,调用recycle()方法把它释放 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SaleProgressView); //获取XML数据,初始化控件 sideColor = ta.getColor(R.styleable.SaleProgressView_sideColor,0xffff3c32); textColor = ta.getColor(R.styleable.SaleProgressView_textColor,0xffff3c32); sideWidth = ta.getDimension(R.styleable.SaleProgressView_sideWidth,dp2px(2)); overText = ta.getString(R.styleable.SaleProgressView_overText); nearOverText = ta.getString(R.styleable.SaleProgressView_nearOverText); textSize = ta.getDimension(R.styleable.SaleProgressView_textSize,sp2px(16)); isNeedAnim = ta.getBoolean(R.styleable.SaleProgressView_isNeedAnim,true); ta.recycle(); } private void initPaint() { sidePaint = new Paint(Paint.ANTI_ALIAS_FLAG); //消除锯齿 /** * Paint.Style.FILL:填充内部 * Paint.Style.FILL_AND_STROKE :填充内部和描边 * Paint.Style.STROKE :描边 */ sidePaint.setStyle(Paint.Style.STROKE); //画笔样式为空心时,设置空心画笔的宽度 sidePaint.setStrokeWidth(sideWidth); //设置画笔颜色 sidePaint.setColor(sideColor); srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG); textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); textPaint.setStyle(Paint.Style.FILL); //设置字体大小 textPaint.setTextSize(textSize); mPorterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); nearOverTextWidth = textPaint.measureText(nearOverText); overTextWidth = textPaint.measureText(overText); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //获取View的宽高 width = getWidth(); height = getHeight(); //圆角半径 radius = height / 2.0f; //留出一定的间隙,避免边框被切掉一部分 if (bgRectF == null) { bgRectF = new RectF(sideWidth, sideWidth, width - sideWidth, height - sideWidth); } if (baseLineY == 0.0f) { Paint.FontMetricsInt fm = textPaint.getFontMetricsInt(); baseLineY = height / 2 - (fm.descent / 2 + fm.ascent / 2); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(!isNeedAnim){ progressCount = currentCount; } if (totalCount == 0) { scale = 0.0f; } else { scale = Float.parseFloat(new DecimalFormat("0.00").format((float) progressCount / (float) totalCount)); } drawSide(canvas); drawBg(canvas); drawFg(canvas); drawText(canvas); //这里是为了演示动画方便,实际开发中进度只会增加 if(progressCount!=currentCount){ if(progressCount totalCount) { currentCount = totalCount; } this.currentCount = currentCount; postInvalidate(); }}
3、使用
4.效果
效果图希望对各位朋友有帮助,谢谢!!!!
更多相关文章
- Android歌词秀设计思路(1)SafetyTimer
- 保存/恢复Activity和Fragment状态的最佳实践(译)
- Android(安卓)View构造方法第三参数使用方法详解
- Android中定时执行任务的3种实现方法
- Android(安卓)Lambda表达式
- 《第一行代码:Android(第2版)》,作者郭霖
- Android(安卓)WebView那些坑之上传文件
- Android开发实战(二十一):浅谈android:clipChildren属性
- Android(安卓)进阶 教你打造 Android(安卓)中的 IOC 框架 【View