Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android full screen dialog appears transparent and in the wrong position

I'm trying to add a dialog to my android app which is full screen on small devices (e.g. mobile phone) but a standard dialog on large devices (e.g. tablets). This follows the logic laid out in the material design specification.

Using the official android dialog guide, using a DialogFragment, I end up with a transparent dialog that overlays the action bar:

enter image description here

Below is the source code.

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>

UPDATE 1 (24-06-2015)

I'm now using the android Theme.AppCompat.NoActionBar theme and have a FrameLayout in the main activity. I still get the same problem (image updated).

  • Is it wrong for me to assume that the built in theme will contain a background colour for the dialog? You know, a sane default? I know for sure that if I just show a dialog the normal way it gets a background colour.
  • I assume the CoordinatorLayout I added causes the dialog to overlay the action bar even though I'm using an embedded FrameLayout. Why is that? I need the CoordinatorLayout so the FloatingActionButton is in the correct position.
like image 342
Jon Avatar asked Nov 10 '22 10:11

Jon


1 Answers

@cutoff was correct. My update failed because the root layout is a CoordinatorLayout instead of a LinearLayout or something equally good. The example below uses a 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>

More details about this solution can be found in this question, including why a DialogFragment is insufficient for anything other than completely full-screen.

like image 151
Jon Avatar answered Nov 14 '22 21:11

Jon