web-dev-qa-db-ja.com

ValueAnimatorを使用したLinearLayoutコンテナの高さのアニメーション

一部のボタンとテキストビューのコンテナとして使用するLinearLayoutがあります。これは、ユーザーが「表示」ボタンを押したときにレイアウトが下にスライドするような印象を与えるために高さをアニメーション化したいものです。

XmlでLinearLayoutをlayout_height = "0dp"およびvisibility = "gone"に設定しました。次に、表示されるように設定し、コンテンツをラップするために必要な高さを設定します。現時点では、アニメーションでもまったく問題があります。ラップコンテンツの高さは気にしないでください。

これがアニメーションの私の方法です:

private void toggle(final LinearLayout v) {
    v.setVisibility(View.VISIBLE);
    ValueAnimator va = ValueAnimator.ofInt(0, 300);
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer value = (Integer) animation.getAnimatedValue();
            v.getLayoutParams().height = value.intValue();
            v.invalidate();

        }
    });

    va.start();
}

おそらく問題は、どのようにLinearLayoutの高さを設定しているのでしょうか?または、ValueAnimatorの機能を誤解していますか? Chet Haaseのブログ投稿を見回しましたが、特定の高さのアニメーションの例は含まれていません。また、3.0以降のAPIを使用して高さのアニメーションを操作する方法の良い例を見つけることもできませんでした。これについていくつかの助けが欲しいと思います、ありがとう!

23
span

このブログ投稿を見てください: http://tech.chitgoks.com/2011/10/29/Android-animation-to-expand-collapse-view-its-children/view.invalidate()を使用してレイアウトを再描画しないでください。 view.requestLayout()を使用する必要があります。

したがって、コードは次のようになります。

ValueAnimator va = ValueAnimator.ofInt(0, height);
    va.setDuration(700);
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer value = (Integer) animation.getAnimatedValue();
            v.getLayoutParams().height = value.intValue();
            v.requestLayout();
        }
    });

LinearLayoutの高さを取得してアニメーションを動的にする方法に関するメモを追加したかっただけです。高さを取得するには、すべてのビューを最初に描画する必要があります。そのため、描画が完了したことを通知するイベントをリッスンする必要があります。これは、次のようにonResume()メソッドから実行できます(私のxmlでは、コンテナーを高さのwrap_contentに宣言し、それを表示することもできるので、最初から非表示にしたいので、測定の後で行います)。

@Override
    public void onResume() {
        super.onResume();
        final ViewTreeObserver vto = filterContainer.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                height = filterContainer.getHeight();
                filterContainer.setVisibility(View.GONE);
                filterContainer.getLayoutParams().height = 0;
                filterContainer.requestLayout();
                ViewTreeObserver obs = filterContainer.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);
            }
        });
    }
60
span