定时无模式对话框

问题描述 投票:10回答:4

有没有显示无模式对话框的对话框?该对话框允许用户与对话框之前的屏幕上的内容进行交互,但是如果被按下,则还允许用户与对话框进行交互?

我知道Toasts,但是它们不允许与弹出窗口进行交互。

我知道对话框,但是它们是模态的,不允许与背景交互。

我知道通知,但是我想要在屏幕上可见的东西。

我基本上希望能够玩游戏或类似的东西,并且弹出窗口显示我有新的电子邮件或类似的东西。我可以单击它查看我的电子邮件,但是如果我想继续玩游戏,可以等待它消失。在Android中可以吗?

android dialog modal-dialog modeless
4个回答
12
投票

是,创建一个样式为Theme.Dialog的活动。这是一个正常的活动,看起来像一个对话框,同时处于无模式且接受事件。

示例:

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

编辑

确实Theme.Dialog模糊了基础活动并使之不可访问。我在这里有一个类似的要求,我必须显示带有文本和取消按钮的上传进度对话框。主要问题在于设置WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL和重置WindowManager.LayoutParams.FLAG_DIM_BEHIND

创建具有自定义内容的对话框:

    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);

这是此对话框的布局:

<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>

4
投票

只需在对话框中添加FLAG_NOT_TOUCH_MODAL标志

dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);  

0
投票

我的实现有点黑,但是还允许按钮被后台窗口捕获

_wm = this.getWindowManager();
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
_view = layoutInflater.inflate(R.layout.notification, null);

_params = new WindowManager.LayoutParams();
_params.height = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
_params.width = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
_params.flags = 
    // this is to keep button presses going to the background window
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
    // this is to enable the notification to recieve touch events
    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
// background transparant
_params.format = PixelFormat.TRANSLUCENT;
_gravity = Gravity.TOP;//Gravity.BOTTOM;

_wm.addView(_view, _params);

0
投票

只是您不想使用活动或Theme.Dialog的DialogFragment冒险的补充

Chooser.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_margin="@dimen/activity_horizontal_margin"
    android:background="@drawable/dialog_bg">

    <RelativeLayout
        android:id="@+id/layout_Camera"
        android:layout_width="0dp"
        android:layout_weight = "0.25"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/camera"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_centerHorizontal="true"
            android:src="@drawable/ic_menu_camera_holo_dark" />

        <TextView
            android:id="@+id/tvCamera"
            android:layout_margin="@dimen/margin_very_small"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textAlignment="center"
            android:layout_below="@id/camera"
            android:text="Camera"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/layout_Gallery"
        android:layout_width="0dp"
        android:layout_weight ="0.25"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/gallery"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_centerHorizontal="true"
            android:src="@drawable/ic_menu_photo_gallery" />

        <TextView
            android:id="@+id/tvGallery"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textAlignment="center"
            android:layout_below="@id/gallery"
            android:text="Gallery"/>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/layout_RemovePhoto"
        android:layout_width="0dp"
        android:layout_weight="0.25"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/removePhoto"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_centerHorizontal="true"
            android:src="@drawable/ic_menu_remove"/>

        <TextView
            android:id="@+id/tvRemovePhoto"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textAlignment="center"
            android:layout_below="@id/removePhoto"
            android:text="Remove Photo"/>

    </RelativeLayout>

</LinearLayout>

可绘制文件夹中的透明背景

dialog_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="@color/off_white"/>

    <corners
        android:radius="15dp" />

    <padding
        android:left="20dp"
        android:top="20dp"
        android:right="20dp"
        android:bottom="20dp" />

    <margin
        android:left="50dp"
        android:bottom="50dp"
        android:right="50dp"
        android:top="50dp"
        />
</shape>

PhotoChooserFragment

public class photoChooserFragment
        extends DialogFragment {

    onItemSelectedListener listener;
    ImageView imgCamera, imgGallery, imgRemovePhoto;
    TextView tvCamera, tvGallery, tvRemovePhoto;

    public interface onItemSelectedListener {
        void onItemSelected(int position);
    }

    public void onItemSelected(int position) {
         listener.onItemSelected(position);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // Activities containing this fragment must implement its listener.
        if (!(activity instanceof onItemSelectedListener)) {
            throw new IllegalStateException(
                    "Activity must implement fragment's callbacks.");
        }

        listener = (onItemSelectedListener) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.chooser, null, false);

        imgCamera = view.findViewById(R.id.camera);
        imgGallery = view.findViewById(R.id.gallery);
        imgRemovePhoto = view.findViewById(R.id.removePhoto);

        tvCamera = view.findViewById(R.id.tvCamera);
        tvGallery = view.findViewById(R.id.tvGallery);
        tvRemovePhoto = view.findViewById(R.id.tvRemovePhoto);

        Window window = getDialog().getWindow();
        window.requestFeature(Window.FEATURE_NO_TITLE);
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        WindowManager.LayoutParams windowLP = window.getAttributes();
        //window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
        //       WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        //window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        window.setGravity(Gravity.BOTTOM);
        windowLP.gravity = Gravity.BOTTOM;
        window.setAttributes(windowLP);

        getDialog().setCanceledOnTouchOutside(true);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        imgCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                onItemSelected(1);
            }
        });

        tvCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                onItemSelected(1);
            }
        });

        imgGallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                onItemSelected(2);
            }
        });

        tvGallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                onItemSelected(2);
            }
        });

        imgRemovePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                onItemSelected(3);
            }
        });

        tvRemovePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                onItemSelected(3);
            }
        });
    }

    @Override
    public void onDetach() {
        super.onDetach();
        // Reset the active listener interface to null.
        listener = null;
    }
}

然后在您的活动中添加界面

implements  photoChooserFragment.onItemSelectedListener

并确保已实施

 @Override
    public  void onItemSelected(int position){
        switch (position){
            case 1: //camera
                GetImageFromCamera();
                break;
            case 2: //gallery
                ChooseImageFromGallery();
                break;
        }
    }

现在您可以调用该片段,一个按钮将起作用,在我使用的是floatingbutton上

faBtnCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Show menu
                photoChooserFragment dialog = new photoChooserFragment();
                dialog.show(getSupportFragmentManager(), "chooser");
            }
        });
© www.soinside.com 2019 - 2024. All rights reserved.