Анимация свойства weightSum с использованием ObjectAnimator - PullRequest
7 голосов
/ 01 декабря 2011

Вступление:

У меня есть LinearLayout, который содержит два вложенных LinearLayout, например так:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dual_pane"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:weightSum="1.0">

    <!-- Screen 1 -->
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="#ff0000"
        android:layout_weight="1">
    </LinearLayout>

    <!-- Screen 2 -->
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="#ff6600"
        android:layout_weight="1">
    </LinearLayout>
</LinearLayout>

Изначально я хочу, чтобы "Screen 1" взялДоступна вся ширина экрана.Поэтому мой R.id.dual_pane имеет свой атрибут weightSum равным 1.0.Это отлично работает!если weightSum = 1.0, то Screen 1 занимает весь экран!

После загрузки некоторых ресурсов я изменяю свою R.Sid.dual_pane weightSum на 2.0, в результате чего для Screen 1 и Screen 2 берется 50% от ширины.экрана.Это также работает отлично.Когда weightSum = 2.0, оба экрана занимают 50% ширины.

Проблема:

Я хотел бы анимировать свойство weightSum, поэтому мой Screen2 будет вставлен.Я нацеливаюсь на HoneyComb, поэтому версия minSDK равна 11, и я решил, что с помощью новой инфраструктуры ObjectAnimator я мог бы легко анимировать это свойство, чтобы получить хороший плавный эффект.Я проверил, что LinearLayout действительно имеет методы getWeightSum () и setWeightSum () (я думаю, что это необходимо для использования ObjectAnimator).

Собственные усилия:

Вот мой код для отображения и скрытия Screen2 с помощью ObjectAnimator:

private void showScreen2()
{
    //Not-animated will work...
    //mDualPane.setWeightSum(2.0f);

    // Now try to animate the weightSum
    float ws = mDualPane.getWeightSum();
    ObjectAnimator anim = ObjectAnimator.ofFloat(mDualPane, "weightSum", ws, 2.0f);
    anim.setDuration(5000);
    anim.start();
}

private void hideScreen2()
{
    //Not-animated will work...
    //mDualPane.setWeightSum(1.0f);

    // Now try to animate the weightSum
    float ws = mDualPane.getWeightSum();
    ObjectAnimator anim = ObjectAnimator.ofFloat(mDualPane, "weightSum", ws, 1.0f);
    anim.setDuration(5000);
    anim.start();
}

Здесь мой mDualPane является моим корневым LinearLayout...

Вопрос:

Когда я вызываю эти функции, ничего не происходит.Экран остается таким же, как и раньше.Нужно ли где-нибудь вызывать requestLayout () на моем mDualPane?Я скучаю по некоторым знаниям ObjectAnimator?Или невозможно анимировать свойство weightSum?

ТАКЖЕ:

1) Я не хочу связываться с жестко заданными значениями ширины и анимировать их.Сейчас я хочу 50-50 для обоих экранов, но я мог бы изменить это позже.В любом случае, мне нужно иметь возможность установить конкретное соотношение между двумя значениями ширины.

2) Я рассмотрел LayoutTransition в сочетании с переключением видимости, но безрезультатно

1 Ответ

11 голосов
/ 08 декабря 2011

Я был прав в том смысле, что мне нужно обновить макет самостоятельно:

float ws = mDualPane.getWeightSum();
ObjectAnimator anim = ObjectAnimator.ofFloat(mDualPane, "weightSum", ws, 2.0f);
anim.setDuration(5000);
anim.addUpdateListener(this);
anim.start();

Теперь я добавил UpdateListener в ObjectAnimator, который реализуется моей деятельностью и обновляет макет:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    mDualPane.requestLayout();
}

Мне кажется странным, что ObjectAnimator сам по себе этого не называет, но, в любом случае, именно так он и работает.

Решение, на мой взгляд, особенно приятно, посколькуВы можете очень хорошо анимировать макеты, независимо от размера экрана ...

...