阅读更多 一个常见的效果:控件自动移入屏幕,停留几秒,再移出屏幕。项目中想做,但没找到合适的教程,于是自己写了一个工具类实现这个效果。本人初学android,实现方法肯定不是最优的,这只是一个没有办法的办法。构思很简单:两个动画,一个移入,一个移出,两个动画间插入一个计时器,以下是代码:
动画类(该类可以实现多个控件的同步动画,只要把所有控件传入构造方法即可,如果要执行不同的动画,各个控件单独调用就可以了,同时设置了一个开关用于控制是否执行“移出”的动作):
package net.jackie.util;import android.annotation.SuppressLint;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.animation.Animation;import android.view.animation.TranslateAnimation;import android.view.animation.Animation.AnimationListener;/** * @author jackie * */public class MoveInAndOutAnim {private static final String TAG = "MoveInAndOutAnim";private int animDuration;private int fromXDelta;private int toXDelta;private int fromYDelta;private int toYDelt;private int keepDuration;private View[] views;private TranslateAnimation mMoveInAnim;private TranslateAnimation mMoveOutAnim;private TimerManager tm;private boolean processMoveOutAnim;/** *  * @param animDuration Duration of animation * @param fromXDelta Change in X coordinate to apply at the start of the animation(generally 0) * @param toXDelta Change in X coordinate to apply at the end of the animation * (if you want to make a horizontal moving, move to right if positive value, move to left if negative value) * @param fromYDelta Change in Y coordinate to apply at the start of the animation(generally 0) * @param toYDelt Change in Y coordinate to apply at the end of the animation * (if you want to make a vertical moving, move to bottom if positive value, move to top if negative value) * @param keepDuration Duration to keep the Views displaying * @param processMoveOutAnim whether to process the move out animation * @param views Views to process the animation */public MoveInAndOutAnim(int animDuration, int fromXDelta, int toXDelta,int fromYDelta, int toYDelt, int keepDuration, boolean processMoveOutAnim, View... views) {this.animDuration = animDuration;this.fromXDelta = fromXDelta;this.toXDelta = toXDelta;this.fromYDelta = fromYDelta;this.toYDelt = toYDelt;this.keepDuration = keepDuration;this.views = views;this.processMoveOutAnim = processMoveOutAnim;initMoveOutAnim();initMoveInAnim();initTimer();}private void initMoveInAnim() {mMoveInAnim = new TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelt);mMoveInAnim.setDuration(animDuration);mMoveInAnim.setFillAfter(true);mMoveInAnim.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {if (processMoveOutAnim) {tm.startTimer();}}@Overridepublic void onAnimationRepeat(Animation animation) {}});}private void initMoveOutAnim() {mMoveOutAnim = new TranslateAnimation(toXDelta, fromXDelta, toYDelt, fromYDelta);mMoveOutAnim.setDuration(animDuration);mMoveOutAnim.setFillBefore(true);mMoveOutAnim.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {clearAnim();}@Overridepublic void onAnimationRepeat(Animation animation) {}});}@SuppressLint("HandlerLeak")private void initTimer() {// Initial timer to control closing of 'Too Short' dialog// In fact, delay controls how long to keep the Views, so do not set it to 0tm = new TimerManager(keepDuration, keepDuration);Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch(msg.what) {case TimerManager.LOAD_PROGRESS :for(View view : views) {view.startAnimation(mMoveOutAnim);}tm.closeTimer();break;case TimerManager.CLOSE_PROGRESS :// Do nothingLog.d(TAG, "Timer for 'Keep View' is closed.");break;}}};tm.setHandler(mHandler);}public void startAnim() {for(View view : views) {view.startAnimation(mMoveInAnim);}}private void clearAnim() {for(View view : views) {view.clearAnimation();}}}

以上动画中用到了一个计时器类TimerManager,也是一个工具类,封装了一个计时器,可以单独用于计时器实例的取得:
package net.jackie.util;import java.util.Timer;import java.util.TimerTask;import android.os.Handler;import android.os.Message;/** * Generate a timer object with specified 'delay' and 'period',  * you can handle events with 'TimerManager.LOAD_PROGRESS'  * and 'TimerManager.CLOSE_PROGRESS', then do your progress. * If you want to get 'timerId', just get it from 'arg1' *  * @author jackie * */public class TimerManager {private Handler mHandler;/** Timer **/      private Timer timer = null;      /** TimerTask **/      private TimerTask timerTask = null;    /** Delay Time in milliseconds **/      private int mDelay;    /** Period in milliseconds **/      private int mPeriod;    /** Timer in progressing flag **/      public static final int LOAD_PROGRESS = 0;      /** Timer close flag **/      public static final int CLOSE_PROGRESS = 1;      /** TimerId **/      private int mTimerId = 0;        public TimerManager(int delay, int period) {    this.mDelay = delay;    this.mPeriod = period;    }        /**     *      * @param handler your own handler to handle the events from this timer     * @param delay amount of time in milliseconds before first execution     * @param period amount of time in milliseconds between subsequent executions     */    public TimerManager(Handler handler, int delay, int period) {    this.mHandler = handler;    this.mDelay = delay;    this.mPeriod = period;    }    public void startTimer() {        if (timerTask == null) {            timerTask = new TimerTask() {                @Override                  public void run() {                    Message msg = new Message();                      msg.what = LOAD_PROGRESS;                      msg.arg1 = (int) (++mTimerId);                    if (mHandler != null) {                    mHandler.sendMessage(msg);                    }                }              };            timer = new Timer();              timer.schedule(timerTask, mDelay, mPeriod);          }      }      public void closeTimer() {        if (timer != null) {              timer.cancel();              timer = null;          }          if (timerTask != null) {              timerTask = null;          }          mTimerId = 0;        if (mHandler != null) {        mHandler.sendEmptyMessage(CLOSE_PROGRESS);        }    }        public void setHandler(Handler handler) {    this.mHandler = handler;    }}

用法很简单,只要构造MoveInAndOutAnim,并调用startAnim方法即可:
MoveInAndOutAnim anim = new MoveInAndOutAnim(ANIMATION_DURATION, 0, 0, 0, topBarHeight,SHOW_ADDRESS_DELAY, true, showAddressLL, mLocationIv);anim.startAnim();

showAddressLL和mLocationIv就是我自己的两个控件,一个是LinearLayout一个是ImageView,我需要他们两个同步执行动画效果。

更多相关文章

  1. Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来
  2. 滑轮控件研究二、GestureDetector的深入研究
  3. android SoftKeypad 软键盘的问题
  4. Android(安卓)TextClock的坑(系统12小时强制转换成24小时格式)
  5. Android(安卓)tv 动画效果faq (放大动画 与ScrollView滚动照成 页
  6. android中角标的实现
  7. Android快速自定义控件+实战演示(三)完整键盘和组合回调!
  8. Android输入控件详解
  9. Android仿百度加载动画

随机推荐

  1. Android:实现定时器 Handler的postDelaye
  2. Android中判断是否有声音在播放
  3. android 横屏竖屏设置
  4. Android(安卓)Studio 使用中遇到的问题和
  5. 禁止横竖屏自动切换
  6. 中国Android应用商店汇总
  7. android 状态栏移动到底部
  8. 一个简单、漂亮、功能强大的Android日志
  9. android UI之去掉状态栏
  10. Android中调用摄像头拍照保存,并在相册中