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

时间:2019-07-27 18:37:45

标签: android android-animation

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

如您在视频中所见,我想挤压一个“ ViewGroup”。同时,我希望淡出ViewGroup中原始位置的内容。即不将内容推向右侧。

有什么想法要实现吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用Transition API制作此类动画。声明两个ViewGroup:第一个是水平的,带有剪切/复制按钮,第二个是垂直的,带有搜索/共享按钮。然后,用ViewGroup切换这些TransitionManager。然后只需提供Transition,它描述了第一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)); } } 上的视图是如何显示和分配的。

<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"/>

activity_layout.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_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/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>

popup_2.xml

getTransition

最后,这里是private Transition getTransition(boolean open) { return new AutoTransition(); } 方法。您可以只使用AutoTransition,它可以处理简单的布局更改。

Slide

结果:

with AutoTransition

同样为了演示,我编写了更复杂的过渡,其中第一个视图组上的按钮以 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; } 动画出现/消失。

transitionName

结果:

custom transition

请注意,androix的背景在两种布局中均应相同。 这里的所有过渡类均来自transitionName包,因此代码向后兼容。但是,如果您需要Lollipop之前的设备支持,则应通过ViewCompat.setTransitionName方法设置getInitialProps

您可以检查my another answer并进行更困难/自定义的转换。