背景:我有一些View动态添加TextViews。它就像一个图形/树实现,其中每个TextView都是一个图形。我正在维护这些TextView的邻接列表(它们的id被维护,然后我可以找到ViewById)。
我想要的是:我有一个播放按钮。我想动画TextViews,以便我看到根,然后是它的子,然后是下一个级别。 我所知道的:按下播放按钮后我看不见它们。我正在做BFS这样
Put root TextView in Queue
make it visible
Put all the direct children of root in a Queue
while(!Q.isempty())
{
remove the first element from Queue
// animate
// after end of animation loop through the adjacency list of this node
// and put all of its children in the queue
}
问题:无论我们尝试什么,第一个元素被删除,Q再次填充子项,然后qeueue中所有元素的动画立即开始并立即结束。 换句话说,动画在代码完成之前不会启动。 我已经尝试将子项的代码放在AnimationListener的onAnimationEnd中。不行。尝试Thread.sleep,不起作用。
答案 0 :(得分:0)
我认为您的问题是您将startAnimation()
方法视为同步,只有在动画完成后才能完成。但它是异步的:startAnimation()
只是改变视图的状态,告诉他在下一个UI重绘循环中开始动画,并立即进一步。这就是为什么在你的应用程序中所有动画同时执行的原因。 Thread.sleep()
也不起作用,因为它只会冻结UI线程而不会改变其行为逻辑。
解决方案如下:
可以通过setStartOffset(offset)
对象的Animation
方法指定延迟,哪个视图应该在实际开始动画之前等待。如果每个动画都长,例如500毫秒,那么根视图的Animation
对象应该有起始偏移0,对于它的子节点 - 500,对于它们的子节点 - 1000等。
您需要创建包含初始动画克隆的Animation
对象列表,设置它们的起始偏移并传递到相应的视图。
Animation anim = AnimationUtils.loadAnimation(this, R.anim...); // load initial animation from xml
List<Animation> anims = new ArrayList<Animation>;
for (int i=0; i < treeDepth; i++){
anims.set(i, anim.clone());
anims.get(i).setStartOffset(anim.getDuration() * i);
for (...){
// here you apply just created animation to all children of i-th level,
// it can be done later, no difference
view.startAnimation(anims.get(i));
}
}
答案 1 :(得分:0)
看到这个我的启动画面动画,一个接一个
我的布局包含一些观点
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/img_bg"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="@drawable/splash_background" />
<ImageView
android:id="@+id/imageCircle"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="50dp"
android:src="@drawable/circle_bg_1" />
<ImageView
android:id="@+id/imageSale"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="50dp"
android:src="@drawable/avsave_text" />
</RelativeLayout>
res / anim / translate_from_left_to_right.xml中的translate_from_left_to_right动画
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="@android:anim/decelerate_interpolator" >
<translate
android:duration="1000"
android:fromXDelta="-100%"
android:toXDelta="50%" />
res / anim / translate_from_right_to_left.xml中的translate_from_right_to_left动画
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="@android:anim/decelerate_interpolator" >
<translate
android:duration="1000"
android:fromXDelta="100%"
android:toXDelta="-50%" />
res / anim / zoom_out.xml中的zoom_out动画
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="1.5"
android:fromYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1" >
</scale>
最后这是我的SplashActivity.java文件
package com.av.stores;
imprt android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class SplashActivity extends Activity {
private ImageView imgCircle, imgSale;
private ImageView imgSplashBg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
}
@Override
protected void onStart() {
imgCircle = (ImageView) findViewById(R.id.imageCircle);
imgSale = (ImageView) findViewById(R.id.imageSale);
imgSale.setVisibility(View.INVISIBLE);
imgCircle.setVisibility(View.INVISIBLE);
imgSplashBg = (ImageView) findViewById(R.id.img_bg);
Animation zoomAnim = AnimationUtils.loadAnimation(this, R.anim.zoom_out);
final Animation animLeftToRight = AnimationUtils.loadAnimation(this,
R.anim.translate_left_to_right);
final Animation animRightToLeft = AnimationUtils.loadAnimation(this,
R.anim.translate_right_to_left);
imgSplashBg.startAnimation(zoomAnim);
zoomAnim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
imgCircle.startAnimation(animLeftToRight);
}
});
animLeftToRight.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
imgSale.setVisibility(View.VISIBLE);
imgSale.startAnimation(animRightToLeft);
}
});
animRightToLeft.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
new Handler().postDelayed(new Runnable() {
/*
* Showing splash screen with a timer. This will be useful
* when you want to show case your app logo / company
*/
@Override
public void run() {
/*Intent i = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(i);
overridePendingTransition(R.anim.activity_enter,
R.anim.activity_leave);*/
finish();
}
}, 500);
}
});
super.onStart();
}
}