it-swarm.com.ru

Нажмите за пределами диалогового окна Android, чтобы закрыть его?

Мне было интересно, можно ли как-то нажать за пределами всплывающего диалога (или действия с темой диалога), и отклонить его, просто нажав за пределами этого?

Я сделал короткую картину, чтобы проиллюстрировать это:

enter image description here

Обычно вам нужно нажать клавишу «назад», чтобы закрыть диалоговые окна, но в Honeycomb было бы здорово иметь возможность просто постукивать за пределами диалогового окна из-за всех свойств экрана.

37
Michell Bak

Мое приложение представляет собой одно действие с Theme.Holo.Dialog. В моем случае другой ответ не сработал. Он только сделал другие фоновые приложения или стартовый экран для получения сенсорных событий.

Я обнаружил, что использование dispatchTouchEvent работает в моем случае. Я думаю, что это также более простое решение. Вот пример кода о том, как использовать его для обнаружения касаний вне действия с темой Dialog:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Rect dialogBounds = new Rect();
    getWindow().getDecorView().getHitRect(dialogBounds);

    if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
        // Tapped outside so we finish the activity
        this.finish();
    }
    return super.dispatchTouchEvent(ev);
}
47
Jan S.
dialog.setCanceledOnTouchOutside(true) 

Устанавливает, отменяется ли это диалоговое окно при касании за пределами окна.

89
Francesco Vadicamo

Существует метод TouchInterceptor, который будет вызываться при нажатии на всплывающее окно.

Например 

mWindow.setTouchInterceptor(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                    mWindow.dismiss();

                    return true;
                }

                return false;
            }
        });

mWindow это всплывающее окно

И если вам нужна та же функциональность для Activity, вы должны выполнить следующие шаги.

1) Добавить флаг перед методом setContentView(), вызываемым в onCreate();

 getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

    // ...but notify us that it happened.
    getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

2) Переопределить onTouchEvent() событие в Activity

и напишите ниже код

 @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                Toast.makeText(getApplicationContext(), "Finish", 3000).show();
                finish();               
                return true;
            }
            return false;
        }

Полная копия здесь

Деятельность

package net.londatiga.Android;

import Android.app.Activity;
import Android.os.Bundle;

import Android.view.MotionEvent;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.view.View.OnTouchListener;
import Android.view.WindowManager.LayoutParams;

import Android.widget.Button;
import Android.widget.Toast;

public class NewQuickAction3DActivity extends Activity implements OnTouchListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         // Make us non-modal, so that others can receive touch events.
        getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);

        // ...but notify us that it happened.
        getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

        setContentView(R.layout.main);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
            Toast.makeText(getApplicationContext(), "Hi", 3000).show();

            return true;
        }

        return false;
    }
}

Это manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
      package="net.londatiga.Android"
      Android:versionCode="1"
      Android:versionName="1.0">
    <uses-sdk Android:minSdkVersion="7" />

    <application Android:icon="@drawable/icon" Android:label="@string/app_name">
        <activity Android:name=".NewQuickAction3DActivity"
                  Android:label="@string/app_name" Android:theme="@Android:style/Theme.Holo.Dialog">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>
14
Dharmendra

Вы также можете использовать Activity # setFinishOnTouchOutside , если ваш диалог Activity. Это должен быть самый короткий путь для Activitys;)

(Хотя это API 11+. Но API <= 10 обычно имеет нормальный размер экрана.)

5
nmr

Вы можете использовать 

  dialog.setCancelable(true\false); 

Для последних версий Android; 

Это отключит событие OutSide Touch.

5
Amt87

Просто пишу dialog.setCanceledOnTouchOutside (false); и это работает для меня, окно не будет сбрасывать на внешний кран.

4
Sachindra N. Pandey
    dialog = new Dialog(MainActivity.this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.dialog_layout);
    dialog.getWindow().setBackgroundDrawableResource(
            Android.R.color.transparent);
    dialog.setCancelable(false);

    dialog.setCanceledOnTouchOutside(true);

Проверьте, есть ли у вас эта строка кода или нет ....

    dialog.setCanceledOnTouchOutside(true);
3
Manoj Behera

Используйте стиль диалога, а не другие стили.

Например, использовать

public YourCustomDialog(Context context) {
    super(context, Android.R.style.Theme_Holo_dialog_NoActionBar);
}

Когда вы используете другие стили, такие как Theme_Translucent_NoTitleBar , диалог не будет закрыт.

1
Mark

this.setFinishOnTouchOutside (ложь);

вы можете использовать это

1
Gopi Cg

Старый вопрос, но еще одно решение:

  1. Сделайте свою переднюю деятельность полноэкранной. Неиспользуемые макеты: Полноэкранный макет должен иметь прозрачный фон (например, @null или @Android:color/transparent). Внутренний макет должен иметь видимый фон.

  2. Добавьте OnClickListener к невидимому внешнему макету, который finish()es ваша деятельность.

1
laalto

Любые представления в диалоге могут быть настроены на использование события касания, поэтому ниже не будут вызываться.

onCreate(){
    getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            dialog.dismiss();
            return false;
        }
    });
0
jungwhan cho
LayoutParams lp=dialogp.getWindow().getAttributes(); 
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;

Я добавил это, и это работает безупречно на 3.0, но должно работать на всех.

0
a54studio