Search code examples
androiddialogmodal-dialogmodeless

timed modeless dialog


Is there any way to show a modeless dialog--a dialog that allows the user to interact with whatever was on the screen before the dialog but also allows the user to interact with the dialog if pressed?

I know of Toasts, but they don't allow interaction with the popup.

I know of Dialogs, but they're modal and don't allow interaction with the background.

I know of Notifications, but I want something that is visibile on screen.

I basically want to be able to be playing a game or something and a popup appears that I have a new email or something. I can click it to view my email, but I can wait for it to go away if I just want to continue playing my game. Is this possible in Android?


Solution

  • Yes, create an Activity with style Theme.Dialog. This is a normal activity which looks like a dialog, while being modeless and accepting events.

    An example:

    <activity android:name=".activity.dialog.PhotoDialog"
              android:label="@string/photo_dialog_title"
              android:theme="@android:style/Theme.Dialog"/>
    

    Edited:

    Indeed Theme.Dialog blurs the underlying activity and makes it unaccessible. I had a similar requirement here I had to show upload progress dialog with text and cancel button. The main catch is in setting WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL and resetting WindowManager.LayoutParams.FLAG_DIM_BEHIND.

    Created a Dialog with custom content:

        if (progressDialog == null) {
                progressDialog = new Dialog(activityRequestingProgressDialog);
                progressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                progressDialog.setContentView(R.layout.progress_upload);
                progressBar = (ProgressBar) progressDialog.findViewById(R.id.progressBar);
                progressText = (TextView) progressDialog.findViewById(R.id.progressText);
                progressText.setText("0 %");
                progressText.setTextSize(18);
                Button buttonCancel = (Button) progressDialog.findViewById(R.id.btnCancel);
                buttonCancel.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View view) {
                        cancelProgressDialog();
                        stopUpload("Upload cancelled.");
                    }
                });
                Window window = progressDialog.getWindow();
                window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
                window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
                window.setGravity(Gravity.BOTTOM);
                progressDialog.show();
            }
    
            progressText.setText(text);
            progressBar.setProgress(percent);
    

    And this is the layout for this Dialog:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/progressDialog"
              android:orientation="vertical"
              android:layout_height="wrap_content"
              android:layout_width="wrap_content"
              android:layout_centerVertical="true">
    
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center"
              android:textSize="18sp"
              android:padding="10dp"
              android:text="@string/progress_title"/>
    
    <LinearLayout android:id="@+id/progressDialog"
                  android:orientation="horizontal"
                  android:layout_height="wrap_content"
                  android:layout_width="wrap_content"
                  android:padding="10dp"
                  android:layout_centerVertical="true">
    
        <ProgressBar android:id="@+id/progressBar"
                     android:layout_width="150dp"
                     android:layout_height="34dp"
                     android:paddingRight="10dp"
                     android:max="100"
                     android:progress="0"
                     android:fadingEdge="vertical"
                     style="?android:attr/progressBarStyleHorizontal"/>
    
        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_gravity="center"
                  android:id="@+id/progressText"
                  android:paddingRight="10dp"/>
    
        <Button android:layout_height="40dp"
                android:layout_width="80dp"
                android:id="@+id/btnCancel"
                android:text="@string/dialog_cancel"/>
    
    </LinearLayout>
    </LinearLayout>