当前位置: 首页 > 知识库问答 >
问题:

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

施敏达
2023-03-14

我想这样做:https://storage.googleapis.com/spec-host/mio-staging/mio-design/1563837804615/assets/1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv/02-overflowmenu.mp4

我想挤压一个“ViewGroup”,正如你在视频中看到的。与此同时,我想淡出ViewGroup中的内容在其原始位置。即不将内容向右推送。

知道如何实现这一点吗?

谢谢

共有1个答案

孔阳平
2023-03-14

您可以使用转换 API 执行此类动画。声明两个 ViewGroup:第一个是水平的,带有剪切/复制按钮,第二个是垂直的,带有搜索/共享按钮。然后使用 TransitionManager 切换这些 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

<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

<?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>

弹出_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>

这里最后一个是getTransition方法。您可以只使用AutoTransition,它可以处理简单的布局更改。

private Transition getTransition(boolean open) {
      return new 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;
    }

结果:

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

你可以检查我的另一个答案,更难/自定义转换。

 类似资料:
  • 当前为 5.4 版本,稍后将升级到 5.5。在 5.5 中,本节内容被拆分成了多个小节。 使用动画视图 在 Unity 中,动画视图用于预览和编辑游戏对象的动画剪辑。动画视图可以通过菜单 Window -> Animation 打开。 查看游戏对象上的动画 动画视图和层级视图、场景视图以及检视视图紧密耦合。类似于检视视图,动画视图将显示当前选中对象的动画的时间轴和关键帧。你也可以在层级视图或场景视

  • 当项目第一次出现以及用户滚动时,我如何设置<code>RecyclerView 我还在某处读到在用户滚动时不直接支持动画;如果这是真的,我们还有什么办法可以做到吗?

  • 问题内容: 我有一个带有线条的动画,现在我想标记这些点。我尝试了,但尝试不动。这是我的示例代码: 你能帮我吗? 我的下一步是:在这些点中有原始向量。这些向量在每个动画步骤中都会更改其长度和方向。如何为这些动画? 如果没有动画,则可以: 首先,非常感谢您的快速实用的回答! 我已经解决了我的Vector动画问题: 然后在“更新功能”中输入: 更改矢量的开始和结束位置(箭头)。 但是,有100个向量或更

  • 我有一个UIView,其中有一个UILabel作为子视图。 现在我用动画改变UIView的宽度(改变约束的常量属性)并在UIView动画中调用layoutIfNeed...( 视图正在正常调整大小,但UILabel(子视图)将字体大小更改为“结束”大小,但没有像uiview那样正确设置动画。 根据WWDC 2012会话,如果仅更改superview的常量,则子视图应设置动画。 UILabel的最小

  • 动画视图指南 在 Unity 中的动画视图中,你可以直接创建和修改动画剪辑。动画视图的功能强大、操作简单,被设计为外部 3D 动画软件的替代品。除了运动动画外,编辑器还可以为材质和组件添加动画,以及基于动画事件修改动画剪辑,动画事件是一些在特定时间点被调用的函数。 更多相关信息请阅读 动画导入 和 动画脚本。 本章接下来的内容将详细介绍动画视图的个个方面。

  • 问题内容: 我正在尝试为div的背景位置设置动画,但要使其保持平稳。您可以在这里查看我目前的努力结果: 我已经呆了好几个小时了,找不到任何可以在亚像素级别上缓慢而流畅地进行动画处理的东西。我当前的示例是根据此页面上的示例代码制作的 如果无法使用背景位置完成操作,是否有办法伪造具有多个div的重复背景并使用翻译移动这些div? 问题答案: 看看这个例子: