如何ViewGroups一个动画布局属性?布局、属性、动画、ViewGroups

2023-09-05 08:06:38 作者:剑起苍穹云归处

我有以下布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_height="match_parent"
              android:layout_width="match_parent">

    <FrameLayout android:id="@+id/viewgroup_left"
                 android:layout_height="match_parent"
                 android:layout_weight="2"
                 android:layout_width="0dp">

        ... children ... 

    </FrameLayout>

    <LinearLayout android:id="@+id/viewgroup_right"
                  android:layout_height="match_parent"
                  android:layout_weight="1"
                  android:layout_width="0dp"
                  android:orientation="vertical">

        ... children ...

    </LinearLayout>

</LinearLayout>

我最终是这样的:

I end up with something like this:

  +------------------------+------------+
  |                        |            |
  |                        |            |
  |         Left           |   Right    |
  |                        |            |
  |                        |            |
  +------------------------+------------+

在一定的切换被触发,我想这样的宽度扩大到填满整个屏幕动画左。同时,我想,这样它收缩到零的动画权的宽度。后来,当肘节再次触发,我需要的东西恢复到上述状态。

When a certain toggle is toggled, I want to animate Left so that its width expands to fill the entire screen. At the same time, I would like to animate the width of Right so that it shrinks to zero. Later, when the toggle is toggled again, I need to restore things to the above state.

我试着写我自己的动画调用 View.getWidth()但是当我动画回到那个值(通过设置查看。 getLayoutParams()。宽度),它比时就开始扩大。我怀疑我只是做是错误的。我也看到在蜂窝动画的东西所有的文档,但我不希望翻译或规模......我想动画的布局width属性。我不能找到这样的一个例子。

I've tried writing my own Animation that calls View.getWidth() but when I animate back to that value (by setting View.getLayoutParams().width) it is wider than when it began. I suspect I'm just doing it wrong. I have also read all the documentation on the Honeycomb animation stuff, but I don't want to translate or scale... I want to animate the layout width property. I can't find an example of this.

什么是做这种正确的方法是什么?

What is the correct way to do this?

推荐答案

由于没有人帮助你的呢,我的第一个答案是这样一个烂摊子,我会尽量给你正确答案,这个时候, - )

Since noone helped you yet and my first answer was such a mess I'll try to give you the right answer this time ;-)

其实我喜欢这个想法,我认为这是可能是一堆人用一个出色的视觉效果。我会实施正确的观点的溢出(我认为的收缩看起来很奇怪,因为文本扩展到底部)。

Actually I like the idea and I think this is a great visual effect which might be useful for a bunch of people. I would implement an overflow of the right view (I think the shrink looks strange since the text is expanding to the bottom).

但无论如何,这里的code的工作完全正常(你甚至可以切换,而它的动画)。

But anyway, here's the code which works perfectly fine (you can even toggle while it's animating).

快速解释的: 你叫切换用布尔为你的方向,这将开始处理动画调用循环。这将增加或减少的基础上的方向和过去的时间(为一个平滑的计算和动画)两个视图的权重。动画呼叫环路将调用本身只要未达到的开始或结束位置。

Quick explanation: You call toggle with a boolean for your direction and this will start a handler animation call loop. This will increase or decrease the weights of both views based on the direction and the past time (for a smooth calculation and animation). The animation call loop will invoke itself as long it hasn't reached the start or end position.

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="10"
    android:id="@+id/slide_layout">
    <TextView
        android:layout_weight="7"
        android:padding="10dip"
        android:id="@+id/left"
        android:layout_width="0dip"
        android:layout_height="fill_parent"></TextView>
    <TextView
        android:layout_weight="3"
        android:padding="10dip"
        android:id="@+id/right"
        android:layout_width="0dip"
        android:layout_height="fill_parent"></TextView>
</LinearLayout>

活动:

public class TestActivity extends Activity {

    private static final int ANIMATION_DURATION = 1000;

    private View mSlidingLayout;
    private View mLeftView;
    private View mRightView;

    private boolean mAnimating = false;
    private boolean mLeftExpand = true;
    private float mLeftStartWeight;
    private float mLayoutWeightSum;
    private Handler mAnimationHandler = new Handler();
    private long mAnimationTime;

    private Runnable mAnimationStep = new Runnable() {
        @Override
        public void run() {
            long currentTime = System.currentTimeMillis();
            float animationStep = (currentTime - mAnimationTime) * 1f / ANIMATION_DURATION;
            float weightOffset = animationStep * (mLayoutWeightSum - mLeftStartWeight);

            LinearLayout.LayoutParams leftParams = (LinearLayout.LayoutParams)
                    mLeftView.getLayoutParams();
            LinearLayout.LayoutParams rightParams = (LinearLayout.LayoutParams)
                    mRightView.getLayoutParams();

            leftParams.weight += mLeftExpand ? weightOffset : -weightOffset;
            rightParams.weight += mLeftExpand ? -weightOffset : weightOffset;

            if (leftParams.weight >= mLayoutWeightSum) {
                mAnimating = false;
                leftParams.weight = mLayoutWeightSum;
                rightParams.weight = 0;
            } else if (leftParams.weight <= mLeftStartWeight) {
                mAnimating = false;
                leftParams.weight = mLeftStartWeight;
                rightParams.weight = mLayoutWeightSum - mLeftStartWeight;
            }

            mSlidingLayout.requestLayout();

            mAnimationTime = currentTime;

            if (mAnimating) {
                mAnimationHandler.postDelayed(mAnimationStep, 30);
            }
        }
    };

    private void toggleExpand(boolean expand) {
        mLeftExpand = expand;

        if (!mAnimating) {
            mAnimating = true;
            mAnimationTime = System.currentTimeMillis();
            mAnimationHandler.postDelayed(mAnimationStep, 30);
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.slide_test);

        mLeftView = findViewById(R.id.left);
        mRightView = findViewById(R.id.right);
        mSlidingLayout = findViewById(R.id.slide_layout);

        mLeftStartWeight = ((LinearLayout.LayoutParams)
                mLeftView.getLayoutParams()).weight;
        mLayoutWeightSum = ((LinearLayout) mSlidingLayout).getWeightSum();
    }
}