实现倒计时的动画效果

项目要求做一个这样子的gif

View的代码是

package com.example;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * 默认是浅绿色
 * @author lq
 *
 */
public class TimerCountdownView extends View {

	int mMaxSeconds = 0 ;
	float mRateAngle = 0 ;
	private float mMaxAngle = 0;

	/**外圈相关**/
	private float mOutCircleWidth = 2;
	private int mOutCircleColor = 0xff01BCB3;
	//起始角度
	private float mOutStartAngle = 145;
	//扫描角度
	private float mOutSweepAngle = 250;

	/**内圈相关**/
	private float mInCircleWidth = 10;
	private int mInCircleColor = 0xffF5F5F5;
	//起始角度
	private float mInStartAngle = 145;
	//扫描角度
	private float mInSweepAngle = 250;

	/**外圈与内圈的距离**/
	private float mOutAndInPadding = 12; //外援环和小圆环虹之间的间隔

	//发起重回命令
	private int mActionHeartbeat = 1 ;

	//间隔时间
	private int mDelayTime = 1 * 1000 ;

	private CountdownTimerListener mListener ;

	public TimerCountdownView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	private Handler mHandler = new Handler() {

		public void handleMessage(android.os.Message msg) {
			if(msg.what == mActionHeartbeat){
				mMaxAngle = mMaxAngle - mRateAngle;
				mMaxSeconds = mMaxSeconds - 1;
				if (mMaxSeconds >= 0) {
					invalidate();
					mHandler.sendEmptyMessageDelayed(mActionHeartbeat,mDelayTime);
					if(mListener!=null){
						mListener.onCountDown(showTheTimer(mMaxSeconds));
						mListener.onTimeArrive(false);
					}
//					Log.d("", "剩余"+mMaxSeconds+"秒" +"  剩余角度:"+mMaxAngle);
				}else{
					    mListener.onTimeArrive(true);
				}
			}
		};
	};

	public void updateView(){
			mHandler.sendEmptyMessage(mActionHeartbeat);
	}

	public void destroy(){
		mHandler.removeMessages(100);
	}

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

	public void drawInCircle(Canvas canvas){
		Paint paint = new Paint();
		paint.setColor(mInCircleColor);
		paint.setAntiAlias(true);
		paint.setStyle(Style.STROKE);
		paint.setStrokeWidth(mInCircleWidth);
		float left = mOutAndInPadding + mOutCircleWidth;
		float top = left;
		float right = getWidth() - left;
		float bottom = getHeight() - top;
		RectF oval = new RectF(left, top, right, bottom);
		canvas.drawArc(oval, mInStartAngle, mInSweepAngle, false, paint);

	}

	public void drawOutCircle(Canvas canvas){
		Paint paint = new Paint();
		paint.setColor(mOutCircleColor);
		paint.setStyle(Style.STROKE);
		paint.setAntiAlias(true);
		paint.setStrokeWidth(mOutCircleWidth);

		float left = 1;
		float top = left;
		float right = getWidth() - left;
		float bottom = getHeight()- top;
		RectF oval = new RectF(left+mOutCircleWidth, top+mOutCircleWidth, right-mOutCircleWidth, bottom-mOutCircleWidth);

		canvas.drawArc(oval, mOutStartAngle,mMaxAngle , false, paint);

	}

	/**
	 * 设置初始最大时间
	 * @param minute 单位分
	 */
	public void setMaxTime(int minute){
		mMaxAngle = mOutSweepAngle ;
		mMaxSeconds = minute * 60 ;
		mRateAngle = mMaxAngle / mMaxSeconds ;
	}

	public void setOutCicleColor(int color){
		mOutCircleColor = color ;
	}

	public void setOutCicleWidth(int width){
		mOutCircleWidth = width ;
	}

	public void setInCicleColor(int color){
		mInCircleColor = color;
	}

	public void setInCicleWidth(int width){
		mInCircleWidth = width;
	}

	public void setOuterAndInerPadding(int padding){
		mOutAndInPadding = padding ;
	}

	public String showTheTimer(int seconds){
		String timer = "";
		String sminute = "";
		String ssecond = "";
		if(seconds>=0){
			int minute = seconds / 60 ;
			int second = seconds % 60 ;

			if(minute<10){
				sminute = "0"+minute+":";
			}else{
				sminute = minute+":" ;
			}
			if(second<10){
				ssecond = "0"+second;
			}else{
				ssecond = second+"" ;
			}
			timer = sminute + ssecond;
		}else{
			timer = "00:00";
		}
		return timer ;
	}

	public interface CountdownTimerListener{

		//当前倒计时计算的文本  格式 mm-ss
		public void onCountDown(String time);

		//倒计时是否到达
		public void onTimeArrive(boolean isArrive);
	}

	public void addCountdownTimerListener(CountdownTimerListener listener){
		mListener = listener ;
	}
}

xml代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/white" >

      <com.example.TimerCountdownView  android:id="@+id/view2"
								  android:layout_width="120dip"
        							android:layout_height="120dip"
        							android:layout_centerInParent="true"/>
    	<TextView android:id="@+id/timer"
    	    	  android:layout_width="wrap_content"
    	    	  android:layout_height="wrap_content"
    	    	  android:layout_centerInParent="true"
    	    	  android:textColor="#01BCB3"
    	    	  android:textSize="30sp"
    	    	  android:text="00:00"/>
    	<TextView android:id="@+id/timer_hint"
    	    android:layout_below="@+id/timer"
    	    	  android:layout_width="wrap_content"
    	    	  android:layout_height="wrap_content"
    	    	  android:layout_centerInParent="true"
    	    	  android:textColor="#cccccc"
    	    	  android:textSize="13sp"
    	    	    android:layout_marginBottom="10dip"
    	    	  android:text="/分钟\n倒计时"/>
</RelativeLayout>

Activity调用代码

package com.example;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.example.TimerCountdownView.CountdownTimerListener;
import com.example.circleprogressbar.R;

public class SimpleActivity extends Activity {

	private Context mContext;

	TimerCountdownView view ;
	TextView mTimer ;
	  @Override
	    protected void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setContentView(R.layout.activity_base);
	        mContext =this;
	        view = (TimerCountdownView) findViewById(R.id.view2);

	        mTimer = (TextView) findViewById(R.id.timer);

	        view.setMaxTime(1);
	        view.updateView();
	        view.addCountdownTimerListener(litener);
	    }
	  CountdownTimerListener litener = new CountdownTimerListener() {

		@Override
		public void onCountDown(String time) {
			mTimer.setText(time);
		}

		@Override
		public void onTimeArrive(boolean isArrive) {
			if(isArrive){
				Toast.makeText(mContext, "时间到", Toast.LENGTH_SHORT).show();
			}
		}
	};

}
时间: 2024-07-31 11:00:47

实现倒计时的动画效果的相关文章

iOS酷炫动画效果合集

源码地址 https://github.com/YouXianMing/Animations 效果绝对酷炫,包含了多种多样的动画类型,如POP.Easing.粒子效果等等,虽然只开源了半年,却是我好几年开发的积累,代码整齐,简单易懂,求star _(:з」∠)_ 部分效果 细节说明 大部分动画效果是本人自己实现的,部分动画效果使用了别人的开源代码并给出了引用说明,以下列表列举了部分效果: 01. POP动画 02. CAShapeLayer的path动画 03. mask动画 04. Easin

iOS点击查看大图的动画效果

对于图片来说,除了表情包,几乎都会被点击查看大图.今天就讲解一个查看和收起大图的动画效果,先直接看效果图: 如图所示,最开始是一个小图,点击小图可以查看大图.大图会从小图的位置和大小"弹"出来,同时背景变成半透明的阴影.点击大图或者阴影后,收起大图,同样地弹回到小图去,同时去掉阴影背景,就像是一张图片在伸大缩小一样. 现在看看这是怎么实现的.在思考一个动画的实现方法时,把动画的动作进行分解然后再一个个去思考怎么实现是一个好的习惯,我们稍微分解一下,这个动画在显示大图和收起大图的时候做了

iOS 之动画效果

/** type *  各种动画效果  其中除了'fade', `moveIn', `push' , `reveal' ,其他属于私有的API. *  ↑↑↑上面四个可以分别使用'kCATransitionFade', 'kCATransitionMoveIn', 'kCATransitionPush', 'kCATransitionReveal'来调用. *  @"cube"                     立方体翻滚效果 *  @"moveIn"    

Core Animation 动画效果介绍

在开始之前呢,先了解一下UIView和CALayer大体的区别(重点列举了以下四点): UIView继承自 UIResponder,因此UIView 可以处理响应事件,而CALayer继承自NSObject,所以它只是负责内容的创建,绘制. UIView负责对内容的管理,而CALayer则是对内容的绘制 UIView中有关位置的属性只有frame.bounds.center,而CALayer除了具备这些属性之外还有anchorPoint.position. 通过修改CALayer可以实现UIVi

带感”的边框交互动画效果

  效果的原理其实就是"四条边"发生宽度和高度的变化,上下两边是宽度变化,左右两边是高度的变化: 它们发生变化的方向也可以可控的,根据坐标设置即可控制. 下面我们直接上代码: 首先准备基础代码,那四条边并不是真正的border,而是通过标签加以宽高写出来,然后定位到四个方向: <!-- html --> <div class="box"> <div class="topL"></div> <d

iOS开发 QQ粘性动画效果

QQ(iOS)客户端的粘性动画效果 时间 2016-02-17 16:50:00  博客园精华区 原文  http://www.cnblogs.com/ziyi--caolu/p/5195615.html 主题 iOS开发 qq的app中要是有新的联系人发消息过来,相应联系人的cell右边会有一个红色的圆圈表示消息条数.如果去触碰那个圆圈,可以发现它竟然会跟着手指的移动而移动. 在一定范围内,手指离开屏幕,会发现红色圆圈会自动弹性的回到原来的位置.而如果超出一定距离,这个圆圈会做一个销毁的动画,

javascript动画效果之缓冲动画(修改版)

在编写多块同时触发运动的时候,发现一个BUG, timer = setInterval(show, 30);本来show是一个自定义函数,当设为timer = setInterval(show(one,two), 30);时,发现show里面的参数one和two无法被导入,所以需要做以下代码改进和优化 原版的html和css代码在这里javascript动画效果之缓冲动画 js代码如下 1 <script> 2 function $(id) { 3 return typeof id === &

自己动手丰衣足食,为Zepto添加Slide动画效果

一.缘由 公司的移动端项目,采用zepto为主要框架,但是zepto毕竟是精简版的jquery,体积小了,功能自然没有这么强大,特别是动画和选择器这两块,需要我们自己去拓展. 在项目开发过程中,很多页面过渡需要用到动画,简单的show/hide过渡太生硬,对用户不友好,并且移动端大多都是采用slide效果,此文主要是为zepto拓展slide动画. 二.发现 从zepto的在线文档上可以发现一个发布在github上的动画模块,但是缺少slide效果,度娘上找了找,相关的极少,只发现了一个slid

jQuery动画效果(借鉴他人的)

(1)jquery中常见的几种动画效果 (2)动画队列执行的顺序 对于一组元素上的动画效果,有如下两种情况: a) 当在一个animate()方法中应用多个属性时,动画是同时发生的. b) 当以链式的写法应用动画方法时,动画是按照顺序发生的. 对 于多组元素上的动画效果,有如下情况: a) 默认情况下,动画都是同时发生的. b) 当以回调的形式应用动画方式时,动画是按照回调顺序发生的. 另外,在动画方法中,要注意其他非动画的方法会插队,例如css()方法,要使这些非动画的 方法也按照顺序来执行,