UI组件在TransitionManager动画中不可见

问题描述 投票:0回答:1

这是Java Android应用程序中的一个问题,它在MainActivity中具有非常简单的自定义可拖动抽屉。

这是它在Android 10(API级别29)模拟器上运行时的行为,这是预期的行为。

draggableViewApi26

但是问题是,当它在Android L(API级别21)模拟器上运行时,其行为异常如下:

draggableViewApi21

在动画期间,UI组件不可见。但是,当应用程序进入后台并返回时,它们就变得可见。

应用程序的实现细节:

为了检测挥动/拖动触摸手势,使用了GestureDetectorCompat。当检测到甩动手势时,将启动自定义抽屉打开动画。动画是使用ConstraintSetConstraintLayoutTransitionManager来实现的。

这是触摸手势检测和TransitionManager动画的实现。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private boolean mIsDrawerOpened;
    private ConstraintLayout mRootConstraintLayout;
    private final ConstraintSet mDrawerClosedConstraintSet = new ConstraintSet();
    private final ConstraintSet mDrawerOpenedConstraintSet = new ConstraintSet();
    private GestureDetectorCompat mGestureDetector;

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

        // Drawer is initially closed
        mIsDrawerOpened = false;

        mRootConstraintLayout = findViewById(R.id.rootConstraintLayout);

        mDrawerClosedConstraintSet.clone(this, R.layout.activity_main_drawer_closed);
        mDrawerOpenedConstraintSet.clone(this, R.layout.activity_main_drawer_opened);

        mGestureDetector = new GestureDetectorCompat(
                getApplicationContext(),
                new GestureDetector.SimpleOnGestureListener() {

                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

                        // Drag / Fling gesture detected

                        // TODO: Recongnize unwanted drag / fling gestures and ignore them.

                        TransitionManager.beginDelayedTransition(mRootConstraintLayout);

                        // Drawer is closed?
                        if(!mIsDrawerOpened) {
                            // Open the drawer
                            mDrawerOpenedConstraintSet.applyTo(mRootConstraintLayout);
                            mIsDrawerOpened = true;
                        }

                        return true;
                    }

                    @Override
                    public boolean onSingleTapUp(MotionEvent e) {

                        // Single tap detected

                        // TODO: If user has tapped on the drawer, do not close it.

                        TransitionManager.beginDelayedTransition(mRootConstraintLayout);

                        // Drawer is opened?
                        if(mIsDrawerOpened) {
                            // Close the drawer
                            mDrawerClosedConstraintSet.applyTo(mRootConstraintLayout);
                            mIsDrawerOpened = false;
                        }

                        return true;
                    }

                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }
                }
        );
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }
}

这是封闭式抽屉的布局XML。

res / layout / activity_main_drawer_closed.xml

<ConstraintLayout
    android:id="@+id/rootConstraintLayout">

    <ConstraintLayout
        android:id="@+id/drawerConstraintLayout"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        <!-- Constraint start (left) of drawer to end (right) of parent (drawer is outside the parent) -->
        app:layout_constraintStart_toEndOf="parent"
        ... >

        <Button
            android:id="@+id/button1"
            android:text="1"
            ... />

        <Button
            android:id="@+id/button2"
            android:text="2"
            ... />

    </ConstraintLayout>

    <ImageView
        android:id="@+id/notch"
        android:src="@drawable/drawer_notch"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/drawerConstraintLayout"
        ... />

</ConstraintLayout>

这是打开的抽屉的布局XML。

res / layout / activity_main_drawer_opened.xml

<ConstraintLayout
    android:id="@+id/rootConstraintLayout">

    <ConstraintLayout
        android:id="@+id/drawerConstraintLayout"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        <!-- Constraint end (right) of drawer to end (right) of parent (drawer is inside the parent) -->
        app:layout_constraintEnd_toEndOf="parent"
        ... >

        <Button
            android:id="@+id/button1"
            android:text="1"
            ... />

        <Button
            android:id="@+id/button2"
            android:text="2"
            ... />

    </ConstraintLayout>

    <ImageView
        android:id="@+id/notch"
        android:src="@drawable/drawer_notch"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/drawerConstraintLayout"
        ... />

</ConstraintLayout>

来自这两个布局的约束集被用作动画的开始和结束关键帧。

最小SDK版本设置为API级别19。

build.gradle

android {
    defaultConfig {
        minSdkVersion 19
        ...
    }
    ...
}

可以在this GitHub gist中找到完整的实现。

这是Java Android应用程序中的一个问题,它在MainActivity中具有非常简单的自定义可拖动抽屉。它在Android 10(API级别29)模拟器上运行时的行为方式,它是...

android android-constraintlayout android-transitions
1个回答
1
投票

要达到预期效果,您需要在布局android:clipChildren="false"中将ViewGroup添加到根目录ConstaintLayout中。当然,这种解决方案仅适用于您的视图在视口之外的情况。

© www.soinside.com 2019 - 2024. All rights reserved.