参考链接:https://github.com/abcghy/CountDownView
商城中的秒杀倒计时样式,自定义view。
相关gradle依赖
//可选择性的将相关代码给自己写一个时间工具类
implementation 'com.blankj:utilcode:1.3.6'
implementation 'io.reactivex.rxjava2:rxjava:2.1.14'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
1、相关代码
public class CountDownView extends View {
private Context mContext;
private Paint mPaint;
private int mTextSize;
private int mBgColor = Color.WHITE;//定义背景颜色
private int mTextColor = Color.BLACK;//定义字体颜色
private int size = 40;
private long hour;
private long min;
private long sec;
private long mTargetTime;//从什么时候开始倒计时,传入毫秒值。
public CountDownView(Context context) {
this(context, null);
}
public CountDownView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CountDownView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.CountDownView);
// defalutSize = a.getDimensionPixelSize(R.styleable.MyView_default_size, 100);
mTextSize = a.getDimensionPixelSize(R.styleable.CountDownView_textSize, dp2px(12));
a.recycle();
initPaint();
}
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.setStrokeWidth(dp2px(2));
mPaint.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
// mPaint.setColor(Color.BLACK);
// canvas.drawLine(dp2px(-100), 0, dp2px(100), 0, mPaint);
drawRect(canvas, -size);
drawRect(canvas, 0);
drawRect(canvas, size);
mPaint.setColor(mTextColor);
String strHour = hour < 10 ? "0" + hour : hour + "";
canvas.drawText(strHour, dp2px(-size), dp2px(4), mPaint);
String strMinute = min < 10 ? "0" + min : min + "";
canvas.drawText(strMinute, 0, dp2px(4), mPaint);
// drawCenter(canvas, mPaint, strMinute);
String strSec = sec < 10 ? "0" + sec : sec + "";
canvas.drawText(strSec, dp2px(size), dp2px(4), mPaint);
mPaint.setColor(mBgColor);
canvas.drawText(":", dp2px(-18), dp2px(4), mPaint);
canvas.drawText(":", dp2px(18), dp2px(4), mPaint);
}
// Rect r = new Rect();
//
// private void drawCenter(Canvas canvas, Paint paint, String text) {
// canvas.getClipBounds(r);
// int cHeight = r.height();
// int cWidth = r.width();
// paint.setTextAlign(Paint.Align.LEFT);
// paint.getTextBounds(text, 0, text.length(), r);
// float x = cWidth / 2f - r.width() / 2f - r.left;
// float y = cHeight / 2f + r.height() / 2f - r.bottom;
// canvas.drawText(text, x, y, paint);
// }
private void drawRect(Canvas canvas, float x) {
mPaint.setColor(mBgColor);
RectF rect = new RectF(dp2px(x - 15), dp2px(-15f), dp2px(x + 15), dp2px(15f));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawRoundRect(rect, dp2px(4), dp2px(4), mPaint);
} else {
canvas.drawRect(rect, mPaint);
}
}
/**
*调用此方法开始进行倒计时
*/
public void start() {
Observable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
// .subscribe(new Consumer() {
// @Override
// public void accept(Long aLong) throws Exception {
// calculateTargetTime();
// invalidate();
// }
// });
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long aLong) {
calculateTargetTime();
invalidate();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
public void setColor(int bgColor, int textColor) {
mBgColor = bgColor;
mTextColor = textColor;
invalidate();
}
public void setCountDownTime(long targetTime) {
this.mTargetTime = targetTime;
calculateTargetTime();
}
private void calculateTargetTime() {
if (mTargetTime != 0) {
long countDownTime = mTargetTime-System.currentTimeMillis();
if (countDownTime >= 0) {
hour = ConvertUtils.millis2TimeSpan(countDownTime, ConstUtils.TimeUnit.HOUR);
min = ConvertUtils.millis2TimeSpan(countDownTime, ConstUtils.TimeUnit.MIN) % 60;
sec = ConvertUtils.millis2TimeSpan(countDownTime, ConstUtils.TimeUnit.SEC) % 60;
}
}
}
/**
* dp转px
*
* @param dpValue dp值
* @return px值
*/
public int dp2px(float dpValue) {
final float scale = mContext.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
Style文件
应用
private void initCountDownView(BusinessEntity entity) {
CountDownView mCountDownView = findViewById(R.id.count_down_view);
TextView mTitleText = findViewById(R.id.miaosha_text1);
//展示秒杀,根据服务端返回的时间戳格式进行format后转为Date再获取毫秒值
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
long startTime = dateFormat.parse(entity.getRedStartTime()).getTime();
long endTime = dateFormat.parse(entity.getRedEndTime()).getTime();
long duringTime = 0;
int timeFlag = redPointUtil.checkValidDataFlag(entity.getRedStartTime(), entity.getRedEndTime());
if (timeFlag == -1) {//未开始
mTitleText .setText(entity.getTitle());
mTitleText .setTextColor(ColorUtil.rgb(entity.getMiaoShaStartTextColor()));
duringTime = startTime;
} else if (timeFlag == 0) {//已开始
mTitleText .setText(entity.getMenuLittleName());
mTitleText .setTextColor(ColorUtil.rgb(entity.getMiaoShaEndTextColor()));
duringTime = endTime;
}
mCountDownView.setCountDownTime(duringTime);
mCountDownView.setColor(Color.BLACK, Color.WHITE);
mCountDownView.start();
}
根据服务端返回字段动态设置字体颜色----
public class ColorUtil {
//格式对应为rgbStriing=rgba(0,0,255,1),也就是json返回的value值的解析。
public static int rgb(String rgbStriing){
int rgbColor = Color.rgb(0,0,0);
try {
String colorString = rgbStriing.replace("rgba(","").replace(")","");
String[] rgbs = colorString.split(",");
rgbColor = Color.rgb(Integer.parseInt(rgbs[0]),Integer.parseInt(rgbs[1]),Integer.parseInt(rgbs[2]));
return rgbColor;
}catch (Exception e){
e.printStackTrace();
}
return rgbColor;
}
}
检测返回的开始时间和结束时间对比当前时间
可参考时间工具文章:https://www.jianshu.com/p/19f248d5f4c3
/**
* 检查任务是否在有效期内
* 时间比较格式:20180613163000年月日时分秒
*/
public int checkValidDataFlag(String startTime, String endTime) {
int flag = 0;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");//年-月-日
try {
Date currentDate = new Date();
Date startDate = dateFormat.parse(startTime.trim());//开始时间
Date endDate = dateFormat.parse(endTime.trim());//结束时间
if (currentDate.before(startDate)) {
flag = -1;//未开始
} else if (currentDate.after(startDate) && currentDate.before(endDate)) {
flag = 0;//进行中倒计时
}else if(currentDate.after(endDate)){
flag=1;//结束
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
xml布局文件
背景