Android 全屏对话框显示透明且位置错误

Android full screen dialog appears transparent and in the wrong position

我正在尝试向我的 android 应用程序添加一个对话框,该对话框在小型设备(例如移动设备 phone)上是全屏的,但在大型设备(例如平板电脑)上是标准对话框。这遵循 material design specification.

中列出的逻辑

使用 official android dialog guide,使用 DialogFragment,我最终得到一个覆盖操作栏的透明对话框:

下面是源代码。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!-- Use ThemeOverlay to make the toolbar text white -->
        <android.support.design.widget.AppBarLayout
            android:id="@+id/abl_top"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:fitsSystemWindows="true"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways"/>

        </android.support.design.widget.AppBarLayout>
    </android.support.design.widget.CoordinatorLayout>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="10dp"
        android:src="@drawable/ic_add"
        android:clickable="true"/>

</android.support.design.widget.CoordinatorLayout>

MainActivity.java

package com.example.fsdialog;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.view.View;

public class MainActivity extends AppCompatActivity
{

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Setup AppBar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }

        final ActionBar ab = getSupportActionBar();
        ab.setHomeAsUpIndicator(R.drawable.ic_menu);
        ab.setDisplayHomeAsUpEnabled(true);

        // FAB
        FloatingActionButton fab = (FloatingActionButton) findViewById(
                R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager fm = getSupportFragmentManager();
                MyDialogFragment dialog = new MyDialogFragment();

                if (false) {
                    // The device is using a large layout, so show the fragment
                    // as a dialog
                    dialog.show(fm, "MyDialogFragment");
                } else {
                    // The device is smaller, so show the fragment fullscreen
                    FragmentTransaction tx = fm.beginTransaction();
                    tx.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

                    // To make it fullscreen, use the 'content' root view as
                    // the container for the fragment, which is always the root
                    // view for the activity
                    tx.add(R.id.content, dialog)
                      .addToBackStack(null).commit();
                }

            }
        });
    }

}

my_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:rowCount="2"
    android:columnCount="2">

    <TextView
        android:id="@+id/text_date1"
        android:layout_row="0"
        android:layout_column="0"
        android:text="17/06/2015"
        style="@android:style/Widget.Holo.Spinner"/>
    <TextView
        android:id="@+id/text_time1"
        android:layout_row="0"
        android:layout_column="1"
        android:text="09:35"
        style="@android:style/Widget.Holo.Spinner"/>
    <TextView
        android:id="@+id/text_date2"
        android:layout_row="1"
        android:layout_column="0"
        android:text="17/06/2015"
        style="@android:style/Widget.Holo.Spinner"/>
    <TextView
        android:id="@+id/text_time2"
        android:layout_row="1"
        android:layout_column="1"
        android:text="11:00"
        style="@android:style/Widget.Holo.Spinner"/>

</GridLayout>

MyDialogFragment.java

package com.example.fsdialog;

import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.view.Window;

public class MyDialogFragment
    extends DialogFragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_dialog, container, false);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.fsdialog"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name"
                 android:icon="@drawable/ic_launcher">
        <activity android:name="MainActivity"
                  android:label="@string/app_name"
                  android:theme="@style/Theme.AppCompat.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

更新 1 (24-06-2015)

我现在使用的是 android Theme.AppCompat.NoActionBar 主题,主 activity 中有一个 FrameLayout。我仍然遇到同样的问题(图片已更新)。

@cutoff 是正确的。我的更新失败了,因为根布局是 CoordinatorLayout 而不是 LinearLayout 或其他同样好的东西。下面的示例使用 DrawerLayout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CoordinatorLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <!-- Use ThemeOverlay to make the toolbar and tablayout text
                 white -->
            <android.support.design.widget.AppBarLayout
                android:id="@+id/abl_top"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:fitsSystemWindows="true"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    app:layout_scrollFlags="scroll|enterAlways"/>

            </android.support.design.widget.AppBarLayout>
        </android.support.design.widget.CoordinatorLayout>

        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_view"/>

</android.support.v4.widget.DrawerLayout>

有关此解决方案的更多详细信息可以在 中找到,包括为什么 DialogFragment 对于除了完全全屏以外的其他任何东西都不够。