【问题标题】:How to animate 2 layouts with margins from top to bottom and from bottom to top如何使用从上到下和从下到上的边距为 2 个布局设置动画
【发布时间】:2015-05-05 07:58:24
【问题描述】:

我正在尝试创建一个具有 2 种布局的应用程序:一种在顶部,一种在底部。我希望当你点击一个布局时,2 次改变位置,一次爬升,另一次下降。

但我有几个问题:

  • 布局 2 扰乱了他们的位置
  • 2个布局在安装前会从屏幕上消失

我怎样才能纠正我的错误?谢谢

MainActivity.java

public class MainActivity extends Activity {

RelativeLayout rl_footer, rl_footer2;
ImageView iv_header, iv_header2;
boolean isBottom = true;
Button btn1;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rl_footer = (RelativeLayout) findViewById(R.id.rl_footer);
    rl_footer2 = (RelativeLayout) findViewById(R.id.rl_footer2);

    iv_header = (ImageView) findViewById(R.id.iv_up_arrow);
    iv_header2 = (ImageView) findViewById(R.id.iv_up_arrow2);

    iv_header.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (isBottom) {

                SlideToAbove1();
                SlideToDown2();
                isBottom = false;

            } else {

                SlideToDown1();
                SlideToAbove2();
                isBottom = true;
            }
        }
    });
}

public void SlideToAbove1() {

    Animation slide = null;
    slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            0.0f, Animation.RELATIVE_TO_SELF, -5.0f);

    slide.setDuration(600);
    slide.setFillAfter(true);
    slide.setFillEnabled(true);
    rl_footer.startAnimation(slide);

    slide.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {

            rl_footer.clearAnimation();

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    rl_footer.getWidth(), rl_footer.getHeight());
            lp.setMargins(20, 20, 0, 0);
            lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            rl_footer.setLayoutParams(lp);
        }
    });
}

public void SlideToAbove2() {

    Animation slide = null;
    slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            0.0f, Animation.RELATIVE_TO_SELF, -5.0f);

    slide.setDuration(600);
    slide.setFillAfter(true);
    slide.setFillEnabled(true);
    rl_footer2.startAnimation(slide);

    slide.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {

            rl_footer2.clearAnimation();

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    rl_footer2.getWidth(), rl_footer2.getHeight());
            lp.setMargins(0, 20, 20, 0);
            lp.addRule(RelativeLayout.ALIGN_PARENT_TOP | RelativeLayout.ALIGN_PARENT_RIGHT);
            rl_footer2.setLayoutParams(lp);
        }
    });
}

public void SlideToDown1() {

    Animation slide = null;
    slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            0.0f, Animation.RELATIVE_TO_SELF, 5.2f);

    slide.setDuration(600);
    slide.setFillAfter(true);
    slide.setFillEnabled(true);
    rl_footer.startAnimation(slide);

    slide.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {

            rl_footer.clearAnimation();

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    rl_footer.getWidth(), rl_footer.getHeight());
            lp.setMargins(20, 0, 0, 20);
            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            rl_footer.setLayoutParams(lp);
        }
    });
}

public void SlideToDown2() {

    Animation slide = null;
    slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
            Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
            0.0f, Animation.RELATIVE_TO_SELF, 5.2f);

    slide.setDuration(600);
    slide.setFillAfter(true);
    slide.setFillEnabled(true);
    rl_footer2.startAnimation(slide);

    slide.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {

            rl_footer2.clearAnimation();

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    rl_footer2.getWidth(), rl_footer2.getHeight());
            lp.setMargins(0, 0, 20, 20);
            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM | RelativeLayout.ALIGN_PARENT_RIGHT);
            rl_footer2.setLayoutParams(lp);
        }
    });
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000" >

<RelativeLayout
    android:id="@+id/rl_footer"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_alignParentTop="true"
    android:layout_margin="20dp"
    android:background="#666666" >

    <ImageView
        android:id="@+id/iv_up_arrow"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:background="#000000" />

    <TextView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="1"
        android:textColor="#FFFFFF"
        android:textSize="30sp" />
</RelativeLayout>

<RelativeLayout
    android:id="@+id/rl_footer2"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:layout_margin="20dp"
    android:background="#666666" >

    <ImageView
        android:id="@+id/iv_up_arrow2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:background="#FFFFFF" />

    <TextView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="2"
        android:textColor="#000000"
        android:textSize="30sp" />
</RelativeLayout>

</RelativeLayout>

【问题讨论】:

    标签: android animation layout


    【解决方案1】:

    我开发了一个动画子类来做这件事。代码如下:

    public class MarginAnimation extends Animation
    {
        private View mView;
        private int mTargetTopMargin;
        private int mTargetLeftMargin;
    
        private int mStartTopMargin;
        private int mStartLeftMargin;
    
        public MarginAnimation(View view, int targetTopMargin, int targetLeftMargin)
        {
            mView = view;
            mTargetTopMargin = targetTopMargin;
            mTargetLeftMargin = targetLeftMargin;
    
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mView.getLayoutParams();
            mStartTopMargin = params.topMargin;
            mStartLeftMargin = params.leftMargin;
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t)
        {
            // I assume the view is inside a RelativeLayout. Change as required.
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mView.getLayoutParams();
    
            params.topMargin = (int)(mStartTopMargin + (mTargetTopMargin - mStartTopMargin) * interpolatedTime);
            params.leftMargin = (int)(mStartLeftMargin + (mTargetLeftMargin - mStartLeftMargin) * interpolatedTime);
    
            mView.setLayoutParams(params);
        }
    
        @Override
        public boolean willChangeBounds()
        {
            return true;
        }
    }
    

    用法:

    MarginAnimation animation = new MarginAnimation(view, targetTopMargin, targetLeftMargin);
    view.startAnimation(animation);
    

    我应该注意,调用布局更改的动画在性能方面并不是 Android 中的最佳选择,但它应该可以完成工作。

    如果可以,请尝试在 translationX/Y 上执行动画并仅在动画的开头/结尾执行布局 (margin) 更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      • 2019-09-02
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      相关资源
      最近更新 更多