【问题标题】:Animate TextViews one by one in Queue在队列中一个一个地为 TextViews 设置动画
【发布时间】:2014-04-15 04:34:16
【问题描述】:

背景:我有一些动态添加的 TextView 的视图。它就像一个图/树实现,其中每个 TextView 都是一个图。我正在维护这些 TextViews 的邻接列表(它们的 id 被维护,然后我可以 findViewById)。

我想要什么:我有一个播放按钮。我想为 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 会再次填充子元素,然后队列中所有元素的动画会立即开始并立即结束。 换句话说,动画在代码完成之前不会开始。 我已经尝试将儿童人口的代码放在 AnimationListener 的 onAnimationEnd 中。不工作。试过 Thread.sleep,不行。

【问题讨论】:

    标签: android animation textview android-animation


    【解决方案1】:

    我想您的问题是您将 startAnimation() 方法视为同步,它应该仅在动画完成后完成。但它是异步的:startAnimation() 只是改变了视图的状态,告诉他在下一个 UI 重绘循环时开始为自己设置动画,然后立即继续。这就是为什么在您的应用程序中所有动画都是同时执行的。 Thread.sleep() 也不起作用,因为它只是冻结 UI 线程而不改变其行为逻辑。

    解决办法如下:

    可以通过Animation 对象的setStartOffset(offset) 方法指定延迟,在实际开始动画之前应该等待哪个视图。如果您的每个动画都长,例如 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));
        }
    }
    

    【讨论】:

    • 感谢您的回复。这是我的第一个 android 项目,所以我有点不知道动画的东西。我们应该在xml中写什么?现在我想要的只是让 TextViews 再次可见(我通过 text_view_obj.setVisibility(View.INVISIBLE) 使它们不可见)
    • @user2759617 没问题!我们一开始都遇到过类似的问题)Android更多是基于事件的,所以理解它的行为逻辑需要一些时间。
    • @user2759617 在代码示例中,我使用loadAnimation 工厂方法从 xml 加载动画,但您可以通过编程方式创建动画对象。还有一点:要设置真正的不可见最好使用View.GONE,因为使用View.INVISIBLE 设置为不可见的视图仍然占据布局空间并且可以接受触摸!
    • 使用xml创建动画的指南在这里:developer.android.com/guide/topics/resources/…你需要Tween animation部分。
    【解决方案2】:

    看到这个我的闪屏动画,一个接一个

    我的布局和一些视图

    <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();
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 2016-12-31
      • 1970-01-01
      相关资源
      最近更新 更多