今天在做开发的时候发现一个奇怪的问题,我使用Timer和Handler配合更新UI界面,Timer每隔一段时间执行一次,发送一次消息,然后Handler接受后更新UI,并在这里使用了动画效果。代码如下:
package com.example.handlerdemo;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private int animCount = -1;
Timer timer = new Timer(true);
Message message;
TextView tv_1, tv_2, tv_3, tv_4, tv_5;
private static Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_1 = (TextView) this.findViewById(R.id.tv_1);
tv_2 = (TextView) this.findViewById(R.id.tv_2);
tv_3 = (TextView) this.findViewById(R.id.tv_3);
tv_4 = (TextView) this.findViewById(R.id.tv_4);
tv_5 = (TextView) this.findViewById(R.id.tv_5);
animPost();
}
private void animPost() {
// new Thread() {
// public void run() {
//
// // while (animCount < 5) {
// // try {
// // Message message = handler.obtainMessage();
// // message.arg1 = animCount;
// // handler.sendMessage(message);
// // animCount++;
// // Thread.sleep(2000);
// //
// // } catch (InterruptedException e) {
// // e.printStackTrace();
// // }
//
//
// }
// }.start();
handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
if (animCount == 0) {
startAnimation(tv_1);
} else if (animCount == 1) {
startAnimation(tv_2);
} else if (animCount == 2) {
startAnimation(tv_3);
} else if (animCount == 3) {
startAnimation(tv_4);
} else if (animCount == 4) {
startAnimation(tv_5);
}
break;
}
super.handleMessage(msg);
}
};
TimerTask task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if (message == null) {
message = new Message();
} else {
message = Message.obtain();
}
message.what = 0;
handler.sendMessage(message);
animCount = animCount + 1;
System.out.print(animCount);
}
};
timer.schedule(task, 0, 3000);
}
// 左右摆动
private void startAnimation(View paramView) {
TranslateAnimation localTranslateAnimation = new TranslateAnimation(2,
0.0F, 2, -0.05F, 1, 0.0F, 1, 0.0F);
localTranslateAnimation.setDuration(1000);
localTranslateAnimation.setInterpolator(new AccelerateInterpolator());
localTranslateAnimation.setRepeatCount(1);
// paramView.setAnimation(localTranslateAnimation);
// localTranslateAnimation.start();
paramView.startAnimation(localTranslateAnimation);//这个方式没有问题
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
结果动画只是执行了一遍,开始我以为是使用Timer以及Handler逻辑的问题,换了几个方案都不行。最后无奈,试着从动画入手,改一下动画的启动方式。开始用的是
paramView.setAnimation(localTranslateAnimation);
localTranslateAnimation.start();
这个方法,这是组件设置动画效果,然后动画开始启动。当然还有组件启动动画的方式,我就试着换这种,发现问题解决了。那到底是什么原因导致的呢?搜了一下,网上没有这方面的资料。那只能去看api了。
从图可知,startAnimmation是立即执行的。也就是说,我们调用了这个方法,动画马上就会执行。而setAnimmation的执行是需要两个先决条件的:
1、动画要设置一个开始时间
2、执行动画的组件的父视图在动画启动之前需要刷新界面。
而我们就是因为没有满足这两个条件,所以出现了问题。