使用ObjectAnimator来实现weightSum属性的动画效果

7

简介:

我有一个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的weighSum更改为2.0,这导致屏幕1和屏幕2均占据屏幕宽度的50%。这也非常完美。当weightSum=2.0时,两个屏幕各占宽度的50%。
问题: 我想通过动画来改变weightSum属性,使得我的Screen2可以滑入。我目标是针对HoneyComb系统,所以minSDK版本是11,我认为可以使用新的ObjectAnimator框架,轻松地动画化该属性,以获得漂亮平滑的效果。我验证了LinearLayout确实具有getWeightSum()和setWeightSum()方法(我认为这是使用ObjectAnimator所必需的)。
自己的努力: 以下是我的代码,用于显示和隐藏屏幕2,使用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...
问题: 当我调用这些函数时,没有任何反应。屏幕保持与之前完全相同的状态。 我需要在mDualPane上的某个地方调用requestLayout()吗?我是否缺乏ObjectAnimator的相关知识?或者weightSum属性无法进行动画处理?
另外: 1)我不想改变硬编码的宽度,并对其进行动画处理。现在我需要两个屏幕都为50-50,但以后可能会更改。无论如何,我需要能够设置两个宽度之间的特定比例。 2)我已经查看了LayoutTransition和切换可见性,但没有成功。
1个回答

11

我的意思是我需要自己更新布局:

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。如果有两个线性布局的权重不相等,那么我们能否将右侧布局移动到左侧并填满整个屏幕?请帮忙。 - user1108995
1
不幸的是,由于LinearLayout的性质,这仅适用于从左到右滑动视图。如果要以相反的方式进行操作,建议您查看https://dev59.com/JG445IYBdhLWcg3wTIjm - Entreco
我的两个视图也在LinearLayout中,但是其权重不相等。 - user1108995
我实现了这个解决方案,但是有一个问题,尽管调用了requestLayout,但我的右侧视图并没有真正增长。这就是你所说的“只能从左到右工作”的意思吗?因为我想让我的右侧增长,这意味着边框向左滑动... - Zordid
2
onAnimationUpdate()中调用requestLayout()是一个不好的主意,因为很容易超过16毫秒的限制。对于任何更复杂或更简单的布局,你都有可能遇到卡顿。这就是为什么ObjectAnimator默认情况下不会这样做的原因。 - Andrii Chernenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接