【问题标题】:Animating weightSum property using ObjectAnimator使用 ObjectAnimator 为 weightSum 属性设置动画
【发布时间】:2011-12-01 12:55:50
【问题描述】:

简介:

我有一个 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>

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

加载一些资源后,我将 R.id.dual_pane weightSum 更改为 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();
}

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

问题:

当我调用这些函数时,什么也没有发生。屏幕与以前完全一样。 我需要在某处调用 mDualPane 上的 requestLayout() 吗?我是否缺少一些有关 ObjectAnimator 的知识?还是无法为 weightSum 属性设置动画?

另外:

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

2) 我查看了 LayoutTransition 与切换可见性的结合,但无济于事

【问题讨论】:

    标签: android android-animation android-linearlayout


    【解决方案1】:

    从某种意义上说,我是对的,我需要自己更新布局:

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

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

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

    我觉得很奇怪,ObjectAnimator 本身并没有调用它,但无论如何,这就是让它工作的方法。

    在我看来,这个解决方案特别好,因为您可以很好地为滑入的布局制作动画,而与屏幕大小无关...

    【讨论】:

    • 嗨,Entreco 如果两个线性布局的权重不相等,我们可以将右侧布局移动到左侧并填满整个屏幕吗?请帮忙
    • 不幸的是,由于 LinearLayout 的性质,这只适用于从左到右滑动视图。反过来,我建议你看看stackoverflow.com/questions/4932462/…
    • 我的两个视图也在 LinearLayout 本身,但权重不相等
    • 我实现了这个解决方案,但遇到的问题是,虽然调用了 requestLayout,但我的右侧视图并没有真正增长。这就是您所说的“只能从左到右工作”的意思吗?因为我希望我的右侧增长,这意味着边框向左滑动......
    • onAnimationUpdate() 中调用requestLayout() 是个坏主意,因为它很容易超过16 毫秒的限制。对于任何或多或少复杂的布局,您肯定会有口吃。这就是ObjectAnimator 默认不这样做的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2012-05-23
    • 1970-01-01
    相关资源
    最近更新 更多