10

LayoutTransitionHoneycomb の新しいクラスを試しています。Viewに追加するときに を所定の位置にスライドさせるアニメーションを設定しましたViewGroupLayoutTransition.APPEARINGビューが最初にレンダリングされてからアニメーションが開始されるまでの間にわずかな遅延 (約 20 ミリ秒) があることに気付きました。言い換えると、ビューが画面に表示された後、ビューは一瞬宙に浮いた後、その場でアニメーションを開始します。ApiDemosこれは、サンプル プロジェクトでも確認できます。ViewGroupレイアウト アニメーションの例では、の APPEARING アニメーションが開始する前に常に遅延があります。他のLayoutTransitionアニメーションを null に設定したり、最終的に非常に短い期間を設定したりしましたが、それでもAPPEARINGアニメーションは遅れます。これが私のコードです:

public class DebugExampleFour extends Activity {
    private int numButtons = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.debug_example_four);

        final ViewGroup frame = (ViewGroup) findViewById(R.id.frame_container);
        LayoutTransition transitioner = new LayoutTransition();

        Animator appearingAnimation = ObjectAnimator.ofFloat(null, "translationX", 600, 0);
        appearingAnimation.setDuration(45);
        appearingAnimation.setStartDelay(0);
        appearingAnimation.setInterpolator(new DecelerateInterpolator());
        appearingAnimation.addListener(new AnimatorListenerAdapter() {
            public void onAnimationEnd(Animator anim) {
                View view = (View) ((ObjectAnimator) anim).getTarget();
                view.setTranslationX(0f);
            }
        });
        transitioner.setAnimator(LayoutTransition.APPEARING, appearingAnimation);
        Animator dummyAnimation = ObjectAnimator.ofInt(0, 1);
        dummyAnimation.setDuration(1);
        dummyAnimation.setStartDelay(0);
        transitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, dummyAnimation);
        transitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, dummyAnimation);
        transitioner.setAnimator(LayoutTransition.DISAPPEARING, dummyAnimation);

        frame.setLayoutTransition(transitioner);

        Button addButton = (Button) findViewById(R.id.addNewButton);
        addButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Button newButton = new Button(DebugExampleFour.this);
                newButton.setText("Click To Remove " + (numButtons++));
                newButton.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        frame.removeView(v);
                    }
                });
                frame.addView(newButton, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

            }
        });    
    }

}

例に沿ったレイアウト ファイルは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:orientation="vertical">
    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:text="Add Button"
        android:id="@+id/addNewButton" />
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:id="@+id/frame_container" android:animateLayoutChanges="true" />
</LinearLayout>

APPEARINGアニメーション前の遅延をなくすにはどうすればよいですか?

4

2 に答える 2

28

右 - 両方のレベルで遅延があります。LayoutTransition のコンテキストで Animator を実行している場合、基になる Animator ではなく、LayoutTransition オブジェクトに期間と startDelay を設定する必要があります (トランジション オブジェクトは、これらのプロパティに独自の値をアニメーターに提供するため)。実行されます)。

この理由は、LayoutTransition は通常、コンテナー内のオブジェクトで実行される一連のアニメーションになるためです。したがって、たとえば、オブジェクトをコンテナに「表示」する場合、トランジションは最初に他のオブジェクトをアニメーション化して邪魔にならないようにし、次に新しいオブジェクトを所定の位置にアニメーション化します。(ApiDemos アプリの場合のように) オブジェクトのセットの真ん中に項目を追加することを想像してください。最初にスペースを作成し、次にオブジェクトをフェード インします。

上記の元のコードの場合、表示されるアニメーションをすぐに実行する必要があるため、APPEARING のトランジション startDelay を 0 に設定する必要があります (上記の回答で行ったように)。

逆に言えば、デフォルトでは DISAPPEARING アニメーションには startDelay がありませんが、CHANGE_DISAPPEARING アニメーションには DISAPPEARING アニメーションの持続時間と等しい startDelay があります。新しい場所。

これらはすべての状況に必ずしも当てはまるとは限らない仮定であるため、特定のケースで必要な動作に応じて動作を制御するために、LayoutTransition に duration/startDelay プロパティがあります。

アニメーション タイプのいずれかを実行したくない場合は、そのアニメーションを null に設定する必要があることにも注意してください (LayoutTransition.setAnimator(int, Animator) のドキュメントを参照してください)。これを dummyAnimator に設定しても、同じ効果はありません。1 つには、これらのアニメーションにカスタム アニメーターを提供した場合でも、LayoutTransition のデフォルトの duration/startDelay 値が引き続き適用されます。

他に知っておくべきこと: 基礎となるタイミング メカニズム (Android だけでなく、私がこれまで取り組んできた他のほとんどのプラットフォームでも) には、ある程度の最小解像度があります。したがって、持続時間を「1」に設定すると、そのアニメーションが 1 ミリ秒で終了しない場合があります。代わりに、1 つのフレームで実行され、次のフレーム (通常、システムが停止していない場合、適切に動作するアプリケーションでのデバイスのリフレッシュ レート) で、アニメーションが終了する必要があることがわかります。

于 2011-04-04T20:39:05.270 に答える
7

両方が判明しAnimatorLayoutTransitionそれぞれに開始遅延値があります。Animator開始遅延はすでにゼロなので、それを変更しても役に立ちませんでした。奇妙なのは、LayoutTransition少なくとも の場合、 の開始遅延がゼロより大きいように見えることですLayoutTransition.APPEARING。作業コードは次のとおりです。

public class DebugExampleFour extends Activity {
    private int numButtons = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.debug_example_four);

        final ViewGroup frame = (ViewGroup) findViewById(R.id.frame_container);
        LayoutTransition transitioner = new LayoutTransition();

        Animator appearingAnimation = ObjectAnimator.ofFloat(null, "translationX", 600, 0);
        appearingAnimation.addListener(new AnimatorListenerAdapter() {
            public void onAnimationEnd(Animator anim) {
                View view = (View) ((ObjectAnimator) anim).getTarget();
                view.setTranslationX(0f);
            }
        });
        transitioner.setAnimator(LayoutTransition.APPEARING, appearingAnimation);
        transitioner.setDuration(LayoutTransition.APPEARING, 300);
        transitioner.setStartDelay(LayoutTransition.APPEARING, 0);

        frame.setLayoutTransition(transitioner);

        Button addButton = (Button) findViewById(R.id.addNewButton);
        addButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Button newButton = new Button(DebugExampleFour.this);
                newButton.setText("Click To Remove " + (numButtons++));
                newButton.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        frame.removeView(v);
                    }
                });
                frame.addView(newButton, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

            }
        });    
    }
}
于 2011-03-10T00:39:54.270 に答える