过渡管理器 - 滑出视图无法正常工作

Transition Manager - Sliding a view out is not working as wanted

我正在尝试使用 Transition + Transition 管理器将此视图滑入和滑出,但是当点击隐藏按钮制作视图时 GONE 它没有滑动动画。但是,显示按钮确实有滑动动画来再次使视图 VISIBLE

    @OnClick(R.id.testBtn)
        public void onTestBtnClick(){
            //hide
            Transition transition = new Slide(Gravity.START);
            transition.setDuration(600);

            TransitionManager.beginDelayedTransition(mParentLayout, transition);
            mLayout.setVisibility(View.GONE);
        }

        @OnClick(R.id.testBtn2)
        public void onTestBtn2Click(){
            //show
            Transition transition = new Slide(Gravity.START);
            transition.setDuration(600);

            TransitionManager.beginDelayedTransition(mParentLayout, transition);
            mLayout.setVisibility(View.VISIBLE);
        }

我尝试将 testBtn2 的重力更改为 Gravity.END,但这会导致它从屏幕右侧开始一直滑动。

布局如下:

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/main_activity_root_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/testBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        android:text="Hide"
        app:layout_constraintStart_toStartOf="parent"/>

    <Button
        android:id="@+id/testBtn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toEndOf="@id/testBtn"
        android:text="show"
        />

    <LinearLayout
        android:id="@+id/layout"
        android:orientation="vertical"
        android:layout_width="100dp"
        android:layout_height="250dp"
        android:background="@drawable/background_side_bar_corners"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

不确定您的代码有什么问题。我已经创建了一个示例,只需尝试下面的代码即可正常工作。确保在布局中为面板视图添加 android:visibility="gone",以便它在首次启动时隐藏。

public class MainActivity extends AppCompatActivity {
boolean isShowing = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_damm_activty);
    findViewById(R.id.testBtn).setOnClickListener(v -> {
        showSlidingPanel(!isShowing);
    });
}

private void showSlidingPanel(boolean show) {
    ViewGroup parent = findViewById(R.id.main_activity_root_view);
    View layout = findViewById(R.id.layout);
    Transition transition = new Slide(Gravity.START);
    transition.setDuration(450);
    transition.addTarget(R.id.layout);
    transition.setInterpolator(new AccelerateDecelerateInterpolator());
    TransitionManager.beginDelayedTransition(parent, transition);
    layout.setVisibility(show ? View.VISIBLE : View.GONE);
    isShowing = show;
}
}

创建这些动画

向上滑动

<translate
    android:duration="400"
    android:fromYDelta="100%"
    android:toYDelta="0" />

向下滑动

<translate
    android:duration="400"
    android:fromYDelta="0"
    android:toYDelta="100%" />

当你想设置布局可见时

binding.musicOptionsLayout.setVisibility(View.GONE); binding.musicOptionsLayout.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_down));

当你想设置布局Gone

binding.musicOptionsLayout.setVisibility(View.GONE); binding.musicOptionsLayout.startAnimation(AnimationUtils.loadAnimation(v.getContext(), R.anim.slide_down));

在 XML..

上设置 android:visibility="gone"

希望这会解决您的问题...

出色的答案here与这个问题非常相似。

我注意到约束布局需要非常具体地设置 - 如果您设置为 GONE 的视图被约束到它的兄弟,这些约束似乎优先于任何过渡管理器动画,即将视图设置为GONE 只是立即杀死它而不是平滑地设置动画,因为另一个视图的约束会立即生效。

我的解决方案是使用指南并限制两个视图,并为转换管理器设置 GuidelineBegin。另一个可能有帮助的选项:

        val rootView = binding.constraintLayout
        val constraintSet = ConstraintSet()
        constraintSet.clone(rootView)
        val transition = AutoTransition()
        transition.duration = 150L
        transition.excludeTarget(R.id.orders_recycler_view, true)

        constraintSet.setGuidelineBegin(binding.guideline.id, if (showingDetailView) 0.px else 64.px)
        TransitionManager.beginDelayedTransition(rootView as ViewGroup, transition)
        constraintSet.applyTo(rootView)