视图动画在其他布局后面显示

14
我想要将一个视图动画到另一个布局,但是我遇到了一个问题,因为我的视图在布局后面。我尝试使用 android:animateLayoutChanges="true",但是没有成功。
我的代码:
layout.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"
    android:animateLayoutChanges="true">
    <RadioButton
        android:id="@+id/radioButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New RadioButton" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="20dp"
        android:animateLayoutChanges="true"
        android:background="#ffffff">

    </LinearLayout>
</RelativeLayout>

我的活动类:

public class MainActivity extends AppCompatActivity {

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

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {

        float x = 300;
        float y = 300;
        RadioButton button = (RadioButton) findViewById(R.id.radioButton);
        button.animate().setDuration(10000).x(x).y(y);
    }
}

LinearLayout在你的RadioButton上方。 - ElDuderino
“转到另一个布局”是指您希望您的 RadioButton 成为 LinearLayout 的子项吗? - tachyonflux
是的,但不要忘记我想要动画效果。因此,需要从一个布局过渡到另一个布局。 - user1851366
6个回答

10

项目将按照它们在布局中的顺序绘制。对于您的布局,将首先绘制RadioButton,然后是LinearLayout。如果它们重叠,LinearLayout将覆盖RadioButton。

解决方案部分#1: 交换RadioButton和LinearLayout的顺序,以便最后绘制RadioButton。

<RelativeLayout
    android:id="@+id/final_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="30dp"
    android:background="#ffffff">
</RelativeLayout>

<RadioButton
    android:id="@+id/radioButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New RadioButton" />

Android开发者网站上有一个更严谨的解释。

解决方案第二部分:与我上面提到的观点无关,但可能同样重要的是,您需要启动动画。下面是更新后的源代码:

public class MainActivity extends AppCompatActivity {

    private RadioButton mRadioButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRadioButton = (RadioButton) findViewById(R.id.radioButton);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {

        float x = 300;
        float y = 300;

        ViewPropertyAnimator animator = mRadioButton.animate().setDuration(10000).x(x).y(y);
        animator.setListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}
            @Override
            public void onAnimationEnd(Animator animation) {
                Log.d(TAG, "onAnimationEnd");
            }

            @Override
            public void onAnimationCancel(Animator animation) {}
            @Override
            public void onAnimationRepeat(Animator animation) {}
        })
        animator.start();
    }

    private static final String TAG = MainActivity.class.getSimpleName();
}

在Android 5.1中,在应用程序启动时测试并进行动画处理。


5

只需将 xml 布局元素的属性设置为 android:clipChildren="false"android:clipToPadding="false",并且不要忘记执行 animatedView.bringToFront()

一个月前我遇到了同样的问题,在苦苦寻找几天后终于找到了解决方案。你可以在这里找到我的问题:链接


2

我不确定你想要实现什么,但是如果你要移动子视图View到其容器之外,你需要在容器上禁用clipChildrenclipToPadding属性,以便看到子视图在父视图之外移动:

    <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"
        android:clipChildren="false"
        android:clipToPadding="false">
        ...
   </RelativeLayout>

无论如何,如果您在某个视图上遇到了z-order问题,您可以使用`bringToFront()`方法;在您的情况下:
    final RadioButton button = (RadioButton) findViewById(R.id.radioButton);
    button.animate().setDuration(10000).x(x).y(y).setListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {
        }

        @Override
        public void onAnimationEnd(Animator animator) {
            button.bringToFront();
        }

        @Override
        public void onAnimationCancel(Animator animator) {
        }

        @Override
        public void onAnimationRepeat(Animator animator) {
        }
    });

2
让我针对480X854像素的mdpi屏幕为您提供解决方案。

480X854 pixel screen

场景1:如果您想让RadioButton跨越LinearLayout并位于RelativeLayout作为父ViewGroup,则需要修复z-order。请按照以下布局进行更改。动画从点A(0,0)开始,相对于RelativeLayout到达点C(300,300)。
<?xml version="1.0" encoding="utf-8"?>
<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"
>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="20dp"
        android:background="#ffffff">
    </LinearLayout>

    <RadioButton
        android:id="@+id/radioButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New RadioButton"
    />  
</RelativeLayout>

场景2:如果您想让RadioButton在LinearLayout上进行动画,并将LinearLayout设置为父ViewGroup,则需要按如下方式设置布局。动画从点B(20,20)(根据layout_margin值)开始,相对于RelativeLayout到点D(320,320)。
<?xml version="1.0" encoding="utf-8"?>
<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"
>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="20dp"
        android:background="#ffffff">

        <RadioButton
            android:id="@+id/radioButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="New RadioButton"
        />
    </LinearLayout>

</RelativeLayout>

场景3:您希望RadioButton跨越LinearLayout动画,LinearLayout作为父ViewGroup,并且您的x或y值超出了LinearLayout边界大小,例如x = 800> 480像素或Y = 1200> 854像素。
<?xml version="1.0" encoding="utf-8"?>
<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"
    <!-- Allow all the children to go out of their parent boundaries -->
    android:clipChildren="false"
>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    <!-- Allow all the children to go out of their parent boundaries -->
    android:clipChildren="false"
    <!-- Do not clip the children at the padding i.e. allow to children go 
    beyond the padding -->
    android:clipToPadding="false"
    android:background="#ffffff">

    <RadioButton
        android:id="@+id/radioButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New RadioButton"
        />
    </LinearLayout>

</RelativeLayout>

希望这有所帮助...
祝编码愉快...

1
根据您回复的Karaokyo先生的评论,我建议这就是您想要的。
RadioButton r1; // suppose you already referenced it
LinearLayout l1; //    //
Animation anim = AnimationUtils.loadAnimation(getBaseContext(), R.anim.abc_slide_in_top);
 // the R.anim. blah blah is the preferred animation you want
//when the time comes
if(r1.getParent() != null)
     ((ViewGroup)r1.getParent()).removeView(r1);
l1.addView(r1);
r1.startAnimation(anim); 
// you can create an animation listener and add the view when the animation
//starts

这里的问题在于,它看起来会像你想要的那样。

1
最简单的解决方案是尝试在xml中重新布局,使RadioButton显示在LinearLayout之后。
在开始动画之前调用bringchildTofront(yourradiobutton) 或者 如果您想更好地控制绘制顺序,则可以扩展RelativeLayout并覆盖。
protected int getChildDrawingOrder (int childCount, int i)

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