首页 > 解决方案 > 如何旋转对话框(带动画)?

问题描述

我目前正在开发一个相机应用程序,并将主要活动锁定为纵向模式,并手动听取方向更改以旋转主要活动上的图标,一切正常。现在我想用我的应用程序的设置对话框复制同样的东西。我尝试旋转对话框的根视图,它确实会旋转,但随后会根据纵向对话框的原始高度进行裁剪。

人像模式:

纵向预览

横向模式:

横向预览

对话框的 XML 代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/settings_bg"
    android:paddingHorizontal="@dimen/settings_dialog_padding_horizontal"
    android:paddingVertical="@dimen/settings_dialog_padding_vertical"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <ToggleButton
            android:id="@+id/location_toggle"
            android:layout_width="@dimen/toggle_button_size"
            android:layout_height="@dimen/toggle_button_size"
            android:textOn=""
            android:textOff=""
            android:checked="false"
            android:background="@drawable/location"
            android:layout_marginStart="4dp"
            android:text="@string/toggle_button"/>

        <ToggleButton
            android:id="@+id/aspect_ratio_toggle"
            android:layout_width="@dimen/toggle_button_size"
            android:layout_height="@dimen/toggle_button_size"
            android:textOn=""
            android:textOff=""
            android:checked="false"
            android:scaleType="centerCrop"
            android:background="@drawable/aspect_ratio"
            android:layout_marginStart="@dimen/settings_toggle_button_spacing"
            android:text="@string/aspect_ratio"/>

        <ToggleButton
            android:id="@+id/torch_toggle_option"
            android:layout_width="@dimen/toggle_button_size"
            android:layout_height="@dimen/toggle_button_size"
            android:textOn=""
            android:textOff=""
            android:layout_marginStart="@dimen/settings_toggle_button_spacing"
            android:checked="false"
            android:scaleType="centerCrop"
            android:background="@drawable/torch"
            android:text="@string/aspect_ratio"/>

        <ImageView
            android:id="@+id/flash_toggle_option"
            android:src="@drawable/flash_off_circle"
            android:layout_width="@dimen/toggle_button_size"
            android:layout_height="@dimen/toggle_button_size"
            android:layout_marginStart="@dimen/settings_toggle_button_spacing"
            android:contentDescription="@string/toggle_flash" />

        <ImageView
            android:id="@+id/grid_toggle_option"
            android:src="@drawable/grid_off_circle"
            android:layout_width="@dimen/toggle_button_size"
            android:layout_height="@dimen/toggle_button_size"
            android:layout_marginStart="@dimen/settings_toggle_button_spacing"
            android:contentDescription="@string/grid_toggle" />

    </LinearLayout>

    <View
        android:layout_marginTop="14dp"
        android:layout_marginBottom="4dp"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@android:color/darker_gray"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingVertical="@dimen/settings_dialog_menu_item_vertical"
            android:paddingHorizontal="@dimen/settings_dialog_menu_item_horizontal"
            android:layout_gravity="end"
            android:orientation="horizontal">

            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="@string/video_quality" />

            <FrameLayout
                android:layout_height="wrap_content"
                android:padding="0dp"
                android:layout_margin="0dp"
                android:layout_width="match_parent">

                <Spinner
                    android:id="@+id/video_quality_spinner"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:padding="0dp"
                    android:layout_margin="0dp"
                    android:layout_gravity="end"/>

            </FrameLayout>
        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="@dimen/settings_dialog_menu_item_horizontal"
            android:paddingVertical="@dimen/settings_dialog_menu_item_vertical"
            android:orientation="horizontal">

            <TextView
                android:layout_alignParentStart="true"
                android:layout_centerVertical="true"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_gravity="center_vertical|start"
                android:text="@string/emphasize_on" />

            <RadioGroup
                android:id="@+id/cm_radio_group"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_gravity="center_vertical|end"
                android:orientation="horizontal">

                <RadioButton
                    android:id="@+id/quality_radio"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/quality"
                    android:checked="true" />

                <View
                    android:layout_width="6dp"
                    android:layout_height="0dp"/>

                <RadioButton
                    android:id="@+id/latency_radio"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/latency"
                    android:checked="false" />

            </RadioGroup>

        </RelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingVertical="@dimen/settings_dialog_menu_item_vertical"
            android:paddingHorizontal="@dimen/settings_dialog_menu_item_horizontal"
            android:orientation="horizontal">

            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="@string/include_audio" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/include_audio_switch"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:checked="true"
                android:layout_gravity="end"/>

        </LinearLayout>
    </LinearLayout>

</LinearLayout>

监听方向变化的代码:

    override fun onOrientationChange(orientation: Int) {
        // [...]
        rotateView(
            settingsDialog.findViewById(R.id.root),
            iconRotation
        )
    }

    private fun rotateView(view: View?, angle: Float) {
        if (view!=null) {
            view.animate().cancel()
            view.animate()
                .rotationBy(angle)
                .setDuration(400)
                .setInterpolator(LinearInterpolator())
                .start()
        }
    }

有什么办法可以解决这个问题吗?

应用程序仓库:https ://github.com/GrapheneOS/Camera

标签: androidxmlkotlinandroid-animationandroid-orientation

解决方案


我解决了这个问题,

  1. 使用额外的 FrameLayout 作为主要父级。

  2. 将对话框的主题设置为确保没有标题栏的全屏对话框(在我的情况下是主应用程序主题)。

  3. 在对话框下方设置透明背景并在 .

  4. (手动加载动画并在布局中的对话框视图上专门调用它们)。

所有这些东西都可以在 Google 上轻松搜索到(以防万一您是 Android 开发新手)。

这是我对我的仓库所做的代码更改。(忽略对 anim/xxx_xxx.xml 文件所做的更改):

https://github.com/GrapheneOS/Camera/commit/13de8a7459754d28385fa0b523fcbf7fc0056ba1


推荐阅读