简体   繁体   English

对父视图进行动画处理而不对子视图进行动画处理

[英]Animating the parent view without animating the child view

I would like to do something like this: https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1563837804615%2Fassets%2F1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv%2F02-overflowmenu.mp4 我想做这样的事情: https : //storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1563837804615%2Fassets%2F1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv%2F02-overflowmenu.mp4

在此处输入图片说明

I would like to squeeze a "ViewGroup" as you can see in the video. 如您在视频中所见,我想挤压一个“ ViewGroup”。 In the meantime, I want to fade out the content in the ViewGroup at its original position. 同时,我希望淡出ViewGroup中原始位置的内容。 ie not pushing the content to the right. 即不将内容推向右边。

Any idea how to implement this? 任何想法如何实现这一点?

Thanks! 谢谢!

You can do such animations with Transition API . 您可以使用Transition API制作此类动画。 Declare two ViewGroup s: first one is horizontal with cut/copy buttons, second is vertical with search/share buttons. 声明两个ViewGroup :第一个是水平的,具有剪切/复制按钮,第二个是垂直的,具有搜索/共享按钮。 Then switch these ViewGroup s with TransitionManager . 然后使用TransitionManager切换这些ViewGroup Then just provide Transition which describes how views on first and second ViewGroup s appears and disappers. 然后仅提供Transition ,该Transition描述了第一个ViewGroup和第二个ViewGroup的视图如何显示和分配。

import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.ChangeBounds;
import androidx.transition.Fade;
import androidx.transition.Scene;
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
import androidx.transition.TransitionSet;

public class MainActivity extends AppCompatActivity {

    private ViewGroup mSceneRoot;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);
        mSceneRoot = findViewById(R.id.sceneRoot);

        showPopup1();
    }

    private void showPopup1() {
        ViewGroup popup1 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_1, mSceneRoot, false);
        popup1.findViewById(R.id.btnGo).setOnClickListener(v -> {
            showPopup2();
        });

        Scene scene = new Scene(mSceneRoot, popup1);
        TransitionManager.go(scene, getTransition(false));
    }

    private void showPopup2() {
        ViewGroup popup2 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_2, mSceneRoot, false);
        popup2.findViewById(R.id.btnBack).setOnClickListener(v -> {
            showPopup1();
        });

        Scene scene = new Scene(mSceneRoot, popup2);
        TransitionManager.go(scene, getTransition(true));
    }
}

activity_layout.xml activity_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/sceneRoot"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom|right"
    android:orientation="vertical"
    android:paddingBottom="150dp"
    android:paddingRight="50dp"
    android:clipToPadding="false"
    android:clipChildren="false"/>

popup_1.xml popup_1.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/popup1"
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:transitionName="bg"
    app:cardElevation="10dp">

    <Button
        android:id="@+id/btnGo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="go"
        android:transitionName="btn_go"/>
</androidx.cardview.widget.CardView>

popup_2.xml popup_2.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/popup2"
    android:layout_width="wrap_content"
    android:layout_height="250dp"
    android:transitionName="bg"
    app:cardElevation="10dp">

    <Button
        android:id="@+id/btnBack"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="back"
        android:transitionName="btn_back"/>
</androidx.cardview.widget.CardView>

Last thing here is getTransition method. 这里的最后一件事是getTransition方法。 You can just use AutoTransition , it can handle easy layout changes. 您可以只使用AutoTransition ,它可以处理简单的布局更改。

private Transition getTransition(boolean open) {
      return new AutoTransition();
}

Result: 结果:

自动转换

Also just for demostration I wrote more complex transition where button on first viewgroup appear/dissapear with Slide animation. 同样为了演示,我编写了更复杂的过渡,其中第一个视图组上的按钮与Slide动画一起出现/消失。

 private Transition getTransition(boolean open) {
        Slide btnGo = new Slide(Gravity.RIGHT);
        btnGo.addTarget("btn_go");

        ChangeBounds bgBounds = new ChangeBounds();
        bgBounds.addTarget("bg");

        Fade btnBack = new Fade();
        btnBack.addTarget("btn_back");

        TransitionSet set = new TransitionSet();
        set.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
        if (open) {
            set.addTransition(btnGo);
            set.addTransition(bgBounds);
            set.addTransition(btnBack);
        } else {
            set.addTransition(btnBack);
            set.addTransition(bgBounds);
            set.addTransition(btnGo);
        }
        return set;
    }

Result: 结果:

自定义过渡

Note that transitionName for background should be same in both layouts. 请注意,两个布局中背景的transitionName应该相同。 All transition classes here are from androix package so code is backward compatible. 这里的所有过渡类都来自androix包,因此代码向后兼容。 But if you need support pre Lollipop devices you should set transitionName via ViewCompat.setTransitionName method. 但是,如果您需要支持Lollipop之前的设备,则应通过ViewCompat.setTransitionName方法设置transitionName

You can check my another answer with more difficult/custom transition. 您可以通过更困难的/自定义的过渡检查我的另一个答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM