使用ObjectAnimator为weightSum属性设置动画

Ent*_*eco 7 android android-animation android-linearlayout

介绍:

我有一个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>
Run Code Online (Sandbox Code Playgroud)

最初,我希望"屏幕1"可以使用所有屏幕宽度.因此,我的R.id.dual_pane的weightSum属性为1.0.这很好用!如果weightSum = 1.0,屏幕1占据整个屏幕!

加载一些资源后,我将R.id.dual_pane weighSum更改为2.0,这会导致屏幕1和屏幕2的屏幕宽度减少50%.这也很完美.当weightSum = 2.0时,两个屏幕占据宽度的50%.

问题:

我想为weightSum属性设置动画,所以我的Screen2将会滑入.我的目标是HoneyComb,所以minSDK版本是11,我想,使用新的ObjectAnimator框架,我可以很容易地动画这个属性,以获得一个很好的平滑效果.我验证了LinearLayout确实有getWeightSum()和setWeightSum()方法(我认为这是使用ObjectAnimator所必需的).

自己的努力:

这是我使用ObjectAnimator显示和隐藏Screen2的代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

在这里,我的mDualPane是我的根LinearLayout ...

题:

当我调用这些函数时,没有任何反应.屏幕保持与以前完全一样.我需要在我的mDualPane上调用requestLayout()吗?我错过了一些关于ObjectAnimator的知识吗?或者是否无法为weightSum属性设置动画?

也:

1)我不想弄乱硬编码的宽度,并动画那些.现在我想要两个屏幕50-50,但我可能会在以后更改它.无论如何,我需要能够设置两个宽度之间的特定比率.

2)我已经看过LayoutTransition并结合切换可见性,但无济于事

Ent*_*eco 11

我是正确的,因为我需要自己更新布局:

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

现在,我向ObjectAnimator添加了一个UpdateListener,它由我的Activity实现并更新布局:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
    mDualPane.requestLayout();
}
Run Code Online (Sandbox Code Playgroud)

对我来说,似乎很奇怪,ObjectAnimator本身并不称呼它,但无论如何,这就是如何使它工作.

在我看来,解决方案特别好,因为你可以很好地动画布局滑动,独立于屏幕尺寸......

  • 在`onAnimationUpdate()中调用`requestLayout()`是一个坏主意,因为它很容易超过16 ms的限制.对于任何或多或少复杂的布局,您都可以保证口吃.这就是为什么`ObjectAnimator`默认不这样做的原因. (2认同)