【问题标题】:android pre honeycomb animation of layoutandroid预蜂窝布局动画
【发布时间】:2014-11-01 02:49:28
【问题描述】:

我正在尝试为布局设置动画以隐藏自身(以便稍后通过动画为其他布局设置动画以取代其位置)。必须与 SDK 8 (android 2.2) 兼容。

如果movingLayout的父级(我的xml中的parent_of_moving_layout)是movingLayout高度的两倍,但我希望父级具有相同的高度,因此movingLayout将自身隐藏在下方,以便我可以为另一个movingLayout2设置动画它的位置。

我已经研究了很长时间,但我找不到解决方案,希望有人有想法(尝试了 setFillAfter 和 setFillEnabled)。

这是我的代码和 xml 来重现结果:

activity_my.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MOVE IT"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/parent_of_moving_layout">

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:background="#ff93c049"
            android:id="@+id/movinglayout"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Test Button"
                android:id="@+id/testbutton"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true" />
        </RelativeLayout>
    </RelativeLayout>

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="80dp"
        android:layout_below="@+id/button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="83dp"></FrameLayout>

</RelativeLayout>

MyActivity.java

package coersum.com.testanimation;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.RelativeLayout;


public class MyActivity extends ActionBarActivity {

    //Button clicked to make movingLayout move (mButton) and button to make sure the objects moved and not only their displays (testButton)
    Button mButton, testButton;
    //layout to move and its LayoutParams (relative seems to be the only one that worked on my tests)
    RelativeLayout movingLayout;
    RelativeLayout.LayoutParams params;
    //used to direction of movement for testing
    String direction = "down";
    //just a counter to see the Log.d changes more clearly
    int count = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(mButtonClickListener);

        testButton = (Button) findViewById(R.id.testbutton);
        testButton.setOnClickListener(testButtonClickListener);

        movingLayout = (RelativeLayout) findViewById(R.id.movinglayout);
        params = (RelativeLayout.LayoutParams) movingLayout.getLayoutParams();

    }

    private View.OnClickListener mButtonClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            TranslateAnimation animation;

            if (direction.equals("down")) {

                animation = new TranslateAnimation(0, 0, 0, 50);

            } else {

                animation = new TranslateAnimation(0, 0, 0, -50);
            }
            animation.setFillAfter(true);
            animation.setFillEnabled(true);
            animation.setDuration(500);
            animation.setAnimationListener(mAnimationListener);
            movingLayout.startAnimation(animation);
        }
    };

    private View.OnClickListener testButtonClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            count++;
            Log.d("Status", "Clicked on Test Button "+count+"  "+direction);
        }
    };

    private Animation.AnimationListener mAnimationListener = new Animation.AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {

            movingLayout.clearAnimation();

            if (direction.equals("down")) {

                direction = "up";
                params.topMargin = params.topMargin + 50;

            } else {

                direction = "down";
                params.topMargin = params.topMargin - 50;

            }

            movingLayout.setLayoutParams(params);
        }
    };


}

【问题讨论】:

    标签: android animation layout margin padding


    【解决方案1】:

    经过几个小时的试验,我找到了一个简单而干净的解决方案(它真的很简单,动画下来然后设置 View.GONE 并把它带回来,设置 View.VISIBLE 在动画之前)!为 DP 添加了一个比例,最后在边距和平移之间做出了区别。

    这是一个更新的 java 文件:

    package coersum.com.testanimation;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    import android.widget.Button;
    import android.widget.RelativeLayout;
    
    
    public class MyActivity extends Activity {
    
        //Button clicked to make movingLayout move (mButton) and button to make sure the objects moved and not only their displays (testButton)
        Button mButton, testButton;
        //layout to move and its LayoutParams (relative seems to be the only one that worked on my tests)
        RelativeLayout movingLayout;
        RelativeLayout.LayoutParams params;
        //used to direction of movement for testing
        String direction = "down";
        //just a counter to see the Log.d changes more clearly
        int count = 0;
    
        int convertedSize;
    
        float scale;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my);
    
            scale = getResources().getDisplayMetrics().density;
            convertedSize = (int) (50 * scale + 0.5f); // my layout is 50dp in height set it to (minus)-your_size to go up instead of down
    
    
            mButton = (Button) findViewById(R.id.button);
            mButton.setOnClickListener(mButtonClickListener);
    
            testButton = (Button) findViewById(R.id.testbutton);
            testButton.setOnClickListener(testButtonClickListener);
    
            movingLayout = (RelativeLayout) findViewById(R.id.movinglayout);
            params = (RelativeLayout.LayoutParams) movingLayout.getLayoutParams();
    
    
        }
    
        private View.OnClickListener mButtonClickListener = new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
    
                TranslateAnimation animation;
    
                if (direction.equals("down")) {
                    animation = new TranslateAnimation(0, 0, 0, convertedSize);
    
                } else {
                    movingLayout.setVisibility(View.VISIBLE); // show the layout before to animate it
                    animation = new TranslateAnimation(0, 0, convertedSize, 0);
                }
    
                animation.setDuration(500);
                animation.setAnimationListener(mAnimationListener);
                movingLayout.startAnimation(animation);
            }
        };
    
        private View.OnClickListener testButtonClickListener = new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
    
                count++; // just for debugging (to make sure the button was gone and not just its display)
                Log.d("Status", "Clicked on Test Button " + count + "  Dir: " + direction + " Size: " + convertedSize);
            }
        };
    
        private Animation.AnimationListener mAnimationListener = new Animation.AnimationListener() {
    
            @Override
            public void onAnimationStart(Animation animation) {
            }
    
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
    
            @Override
            public void onAnimationEnd(Animation animation) {
    
                if (direction.equals("down")) {
                    movingLayout.setVisibility(View.GONE); // once it translated down, remove it so I'll be free to set other layout to visible to use etc
                    direction = "up";
                } else {
                    direction = "down";
                }
    
                movingLayout.setLayoutParams(params);
                movingLayout.clearAnimation();
            }
        };
    
        public void testClick(View view) {
    
    
        }
    
    
    }
    

    如果您只想在屏幕内移动布局(并实际移动对象而不仅仅是它们的“显示”,这是 Honeycomb sdk 下的动画所做的那样,那么边距设置很好,但那不是我的情况所以这个,到目前为止似乎工作得很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多