Коснитесь диалогового окна Android, чтобы отклонить его?
Мне было интересно, возможно ли каким-то образом выйти за пределы всплывающего диалогового окна (или Activity с диалоговой темой) и отбросить его, просто нажав за его пределами?
Я сделал быструю фотографию, чтобы проиллюстрировать это:
![enter image description here]()
Обычно вам нужно нажать клавишу "Назад", чтобы закрыть диалоговые окна, но на Honeycomb было бы здорово иметь возможность просто выходить за пределы диалогового окна из-за всего свойства экрана.
Ответы
Ответ 1
Мое приложение - это одно действие с Theme.Holo.Dialog. В моем случае другой ответ не сработал. Это сделало другие фоновые приложения или экран запуска для получения событий касания.
Я обнаружил, что использование dispatchTouchEvent работает в моем случае. Я думаю, что это также более простое решение. Вот несколько примеров кода, как использовать его для обнаружения ответвлений вне активности с помощью темы "Диалог":
@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);
}
Ответ 2
dialog.setCanceledOnTouchOutside(true)
Устанавливает, отменяется ли это диалоговое окно при касании вне границ окна.
Ответ 3
Существует метод 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()
в действии
и напишите ниже код
@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>
Ответ 4
Вы можете использовать Activity # setFinishOnTouchOutside, если ваше диалоговое окно Activity
. Это должен быть самый короткий путь для Activity
;)
(хотя это API 11+, хотя API <= 10 обычно имеет нормальный размер экрана.)
Ответ 5
Вы можете использовать
dialog.setCancelable(true\false);
Для самых последних версий Android;
Отключит событие outSideTouching.
Ответ 6
Просто я пишу dialog.setCanceledOnTouchOutside(false); и он работает для меня, окно не будет отменено на внешнем кране.
Ответ 7
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);
Ответ 8
Старый вопрос, но еще одно решение:
-
Сделайте полноэкранную активность переднего плана. Usenested layouts: полноэкранный макет должен иметь прозрачный фон (например, @null
или @android:color/transparent
). Внутренний макет должен иметь видимый фон.
-
Добавьте OnClickListener
к невидимому внешнему макету, который finish()
выполняет вашу деятельность.
Ответ 9
Используйте стиль диалога, а не другие стили.
Например, используйте
public YourCustomDialog(Context context) {
super(context, android.R.style.Theme_Holo_dialog_NoActionBar);
}
При использовании других стилей, таких как Тема_Транслюкент_NoTitleBar, диалог не будет отклонен.
Ответ 10
Любые представления в диалоговом окне могут устанавливать, чтобы потреблять событие касания, так что ниже не будет вызываться.
onCreate(){
getWindow().getDecorView().getRootView().setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
dialog.dismiss();
return false;
}
});
Ответ 11
LayoutParams lp=dialogp.getWindow().getAttributes();
lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS;
Я добавил это, и он работает безупречно на 3.0, но должен работать на всех.
Ответ 12
this.setFinishOnTouchOutside(ложь);
вы можете использовать этот