Android实现淘宝客户端倒计时界面
作者:赵凯强 发布时间:2023-09-18 21:25:09
标签:Android,淘宝,倒计时
在前面的文章中,我们分析了淘宝android客户端的一些界面实现和用户体验,今天这篇文章,主要介绍如何使用自定义控件,实现抢购倒计时的功能。
首先,我们看一下实现的效果。
实现效果很简单哈,就是一个倒计时的自定义控件。
下面简单介绍一下实现的思路。
首先,显示时间使用的是Textview,因为没有很特殊的效果,因此,我们可以自己写一个简单的布局文件,来作为显示的界面。
而关于时间的变更,我们使用timer类就可以实现,用一个1000毫秒的Timer,每过一秒,更新一下界面即可。
但是在更新时间的显示数字的时候,有一个问题需要注意,我的思路是用6个Textview来显示时间,因此,时分秒的十位数字和个位数字需要单独显示,个位上显示的数字是0-9,十位上显示的数字范围是0-5,所以需要分开实现。
当秒的十位个位都是0的时候,在过一秒,分的个位就要减一,这就涉及到借位的问题,因此,每变更一次数字,都需要判断是否需要借位。
具体的实现思路,大家还是看代码吧。
/*
* Copyright (c) 2014, 青岛司通科技有限公司 All rights reserved.
* File Name:RushBuyCountDownTimerView.java
* Version:V1.0
* Author:zhaokaiqiang
* Date:2014-9-26
*/
package com.qust.widght;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.qust.rushbuycountdowntimerview.R;
@SuppressLint("HandlerLeak")
public class RushBuyCountDownTimerView extends LinearLayout {
// 小时,十位
private TextView tv_hour_decade;
// 小时,个位
private TextView tv_hour_unit;
// 分钟,十位
private TextView tv_min_decade;
// 分钟,个位
private TextView tv_min_unit;
// 秒,十位
private TextView tv_sec_decade;
// 秒,个位
private TextView tv_sec_unit;
private Context context;
private int hour_decade;
private int hour_unit;
private int min_decade;
private int min_unit;
private int sec_decade;
private int sec_unit;
// 计时器
private Timer timer;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
countDown();
};
};
public RushBuyCountDownTimerView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.view_countdowntimer, this);
tv_hour_decade = (TextView) view.findViewById(R.id.tv_hour_decade);
tv_hour_unit = (TextView) view.findViewById(R.id.tv_hour_unit);
tv_min_decade = (TextView) view.findViewById(R.id.tv_min_decade);
tv_min_unit = (TextView) view.findViewById(R.id.tv_min_unit);
tv_sec_decade = (TextView) view.findViewById(R.id.tv_sec_decade);
tv_sec_unit = (TextView) view.findViewById(R.id.tv_sec_unit);
}
/**
*
* @Description: 开始计时
* @param
* @return void
* @throws
*/
public void start() {
if (timer == null) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
handler.sendEmptyMessage(0);
}
}, 0, 1000);
}
}
/**
*
* @Description: 停止计时
* @param
* @return void
* @throws
*/
public void stop() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
/**
* @throws Exception
*
* @Description: 设置倒计时的时长
* @param
* @return void
* @throws
*/
public void setTime(int hour, int min, int sec) {
if (hour >= 60 || min >= 60 || sec >= 60 || hour < 0 || min < 0
|| sec < 0) {
throw new RuntimeException("Time format is error,please check out your code");
}
hour_decade = hour / 10;
hour_unit = hour - hour_decade * 10;
min_decade = min / 10;
min_unit = min - min_decade * 10;
sec_decade = sec / 10;
sec_unit = sec - sec_decade * 10;
tv_hour_decade.setText(hour_decade + "");
tv_hour_unit.setText(hour_unit + "");
tv_min_decade.setText(min_decade + "");
tv_min_unit.setText(min_unit + "");
tv_sec_decade.setText(sec_decade + "");
tv_sec_unit.setText(sec_unit + "");
}
/**
*
* @Description: 倒计时
* @param
* @return boolean
* @throws
*/
private void countDown() {
if (isCarry4Unit(tv_sec_unit)) {
if (isCarry4Decade(tv_sec_decade)) {
if (isCarry4Unit(tv_min_unit)) {
if (isCarry4Decade(tv_min_decade)) {
if (isCarry4Unit(tv_hour_unit)) {
if (isCarry4Decade(tv_hour_decade)) {
Toast.makeText(context, "时间到了",
Toast.LENGTH_SHORT).show();
stop();
}
}
}
}
}
}
}
/**
*
* @Description: 变化十位,并判断是否需要进位
* @param
* @return boolean
* @throws
*/
private boolean isCarry4Decade(TextView tv) {
int time = Integer.valueOf(tv.getText().toString());
time = time - 1;
if (time < 0) {
time = 5;
tv.setText(time + "");
return true;
} else {
tv.setText(time + "");
return false;
}
}
/**
*
* @Description: 变化个位,并判断是否需要进位
* @param
* @return boolean
* @throws
*/
private boolean isCarry4Unit(TextView tv) {
int time = Integer.valueOf(tv.getText().toString());
time = time - 1;
if (time < 0) {
time = 9;
tv.setText(time + "");
return true;
} else {
tv.setText(time + "");
return false;
}
}
}
项目在我的github上,大家可以下载,也可以提交BUG。
项目地址
来源:https://blog.csdn.net/zhaokaiqiang1992/article/details/39580603


猜你喜欢
- 今天给大家带来的是一块用WPF 实现魔方的小游戏,先看一下效果图 代码如下,先写一个类,用来判断是否可以移动using System;usi
- 一、IDEA下载idea、jdk、tomcat、maven下载地址请参考上一篇博客:https://blog.csdn.net/DwZ735
- 前言前面几篇我们学习的都是单表查询,就是对一张表中的数据进行查询。而实际项目中,基本都会有多张表联合查询的情况,今天我们就来了解下JPA的联
- 一、Lambda 表达式的基础语 * ambda 表达式的基础语法:Java8中引入了一个新的操作符 "->" 该操
- 一、前言前一篇文章已经详细介绍了如何使用Xposed框架编写第一个微信插件:摇骰子和猜拳 * 本文继续来介绍如何使用Xposed框架编写第
- 在Java中如果一个类同时继承接口A与B,并且这两个接口中具有同名方法,会怎么样?动手做实验:interface A{ void
- 生命太短暂,不要去做一些根本没有人想要的东西。本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术
- 本文实例为大家分享了Spring实现默认标签解析流程的具体代码,供大家参考,具体内容如下承接上文,进入parseBeanDefinition
- 本文实例讲述了Android编程使用HTTP协议与TCP协议实现上传文件的方法。分享给大家供大家参考,具体如下:Android上传文件有两种
- C#中,有些类型是可以隐式转换的,我整理了这些可以隐式转换的类型,供大家参考 static
- 很久之前也写过一篇使用Jitpack发布Android开源库的文章,详见Android发布项目到jitpack的完整步骤近来因为工作原因,又
- 声明类定义类:class MyClass { // 字段、构造函数和 // 方法声明}
- 大家好,因为近期做需求中遇到了文件上传这个东西,而且我这个还是跨服务去传输文件的所以我这边使用了httpclient和RestTemplat
- 前言最近在学习Spring Boot结合Redis时看了一些网上的教程,发现这些教程要么比较老,要么不知道从哪抄得,运行起来有问题。这里分享
- 一、注解(annotations)列表@SpringBootApplication:包含了@ComponentScan、@Configura
- 目前Android平台提供了两类动画一类是Tween动画,第二类就是 Frame动画,具体内容介绍请看下文:一类是Tween动画,就是对场景
- 一、连接数据库的配置单独放在一个properties文件中之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中
- 题目要求思路一:模拟迭代依次判断每个节点是否合法:左子树判断是否>low,合法就向左下走,不合法往右下;右子树判断是否<high
- 本文研究的主要是Java中finally和return的关系,具体介绍和实例如下所示。finally 和 return 关系的总结1.try
- 一. CodeCache简介从字面意思理解就是代码缓存区,它缓存的是JIT(Just in Time)编译器编译的代码,简言之codeCac