Я реалізував спеціальний діалог для своєї програми. Я хочу реалізувати, що коли користувач клацне поза діалоговим вікном, діалогове вікно буде відхилено. Що я повинен зробити для цього?
Я реалізував спеціальний діалог для своєї програми. Я хочу реалізувати, що коли користувач клацне поза діалоговим вікном, діалогове вікно буде відхилено. Що я повинен зробити для цього?
Відповіді:
Ви можете скористатись тим, dialog.setCanceledOnTouchOutside(true);
що закриє діалогове вікно, якщо торкнутися його поза межами діалогу.
Щось на зразок,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Або якщо ваш діалог у не-моделі,
1 - Встановіть прапор FLAG_NOT_TOUCH_MODAL
для атрибута вікна вашого діалогу
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - Додайте ще один прапор до властивостей Windows ,, FLAG_WATCH_OUTSIDE_TOUCH
- цей діалог призначений для отримання діалогової події за межами його видимої області.
3 - Переопределення onTouchEvent()
діалогового вікна та перевірте тип дії. якщо тип дії ' MotionEvent.ACTION_OUTSIDE
' означає, що користувач взаємодіє за межами діалогової області. Тож у цьому випадку ви можете зменшити діалог або вирішити, що ви хочете виконати. переглянути звичайний відбиток?
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
this.dismiss();
}
return false;
}
Для отримання додаткової інформації дивіться статтю Як відмовитись від користувацького діалогового вікна на основі сенсорних точок? та Як відхилити ваше немодальне діалогове вікно, якщо торкнутися його поза межами діалогового регіону
Просто використовуйте
dialog.setCanceledOnTouchOutside(true);
Ви можете використовувати цю реалізацію onTouchEvent. Це заважає реагувати під активністю на подій на дотик (як згадувалося Howettl).
@Override
public boolean onTouchEvent ( MotionEvent event ) {
// I only care if the event is an UP action
if ( event.getAction () == MotionEvent.ACTION_UP ) {
// create a rect for storing the window rect
Rect r = new Rect ( 0, 0, 0, 0 );
// retrieve the windows rect
this.getWindow ().getDecorView ().getHitRect ( r );
// check if the event position is inside the window rect
boolean intersects = r.contains ( (int) event.getX (), (int) event.getY () );
// if the event is not inside then we can close the activity
if ( !intersects ) {
// close the activity
this.finish ();
// notify that we consumed this event
return true;
}
}
// let the system handle the event
return super.onTouchEvent ( event );
}
Джерело: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html
Або якщо ви налаштовуєте діалогове вікно за допомогою теми, визначеної у вашому стилі xml, введіть цей рядок у свою тему:
<item name="android:windowCloseOnTouchOutside">true</item>
dialog.setCanceledOnTouchOutside(true);
працює чудово.
Цей метод повинен повністю уникати діяльності, розташованої нижче сірої області пошуку подій клацання.
Видаліть цей рядок, якщо у вас є:
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Поставте це на створеній вами діяльності
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
а потім замініть цей дотик
@Override
public boolean onTouchEvent(MotionEvent ev)
{
if(MotionEvent.ACTION_DOWN == ev.getAction())
{
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// You have clicked the grey area
displayYourDialog();
return false; // stop activity closing
}
}
// Touch events inside are fine.
return super.onTouchEvent(ev);
}
Ви можете спробувати це: -
AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);
або
alertDialog.setCancelable(true);
І якщо у вас є AlterDialog.Builder
тоді, ви можете спробувати це:
alertDialogBuilder.setCancelable(true);
Цей код використовується для використання, коли натискаєте на діалоговому вікні, який перебуває в ході часу, і коли користувач натискає зовнішню сторону діалогового вікна, що час і програмного вводу, і діалогового вікна закриваються.
dialog = new Dialog(act) {
@Override
public boolean onTouchEvent(MotionEvent event) {
// Tap anywhere to close dialog.
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) event.getX(),
(int) event.getY())) {
// You have clicked the grey area
InputMethodManager inputMethodManager = (InputMethodManager) act
.getSystemService(act.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(dialog
.getCurrentFocus().getWindowToken(), 0);
dialog.dismiss();
// stop activity closing
} else {
InputMethodManager inputMethodManager = (InputMethodManager) act
.getSystemService(act.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(dialog
.getCurrentFocus().getWindowToken(), 0);
}
return true;
}
};
Ще одне рішення, цей код був узятий із вихідного коду андроїда. Window
Ви повинні просто додати ці два способи до свого діалогового вихідного коду.
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isShowing() && (event.getAction() == MotionEvent.ACTION_DOWN
&& isOutOfBounds(getContext(), event) && getWindow().peekDecorView() != null)) {
hide();
}
return false;
}
private boolean isOutOfBounds(Context context, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
final View decorView = getWindow().getDecorView();
return (x < -slop) || (y < -slop)
|| (x > (decorView.getWidth()+slop))
|| (y > (decorView.getHeight()+slop));
}
У цього рішення немає цієї проблеми:
Це чудово працює, за винятком того, що діяльність внизу також реагує на дотик. Чи є якийсь спосіб запобігти цьому? - howettl
Наступне працювало для мене:
myDialog.setCanceledOnTouchOutside(true);
Ви можете зробити , background
що займає весь розмір екрану transparent
і слухати onClick
події до dismiss
нього.
Ось код
dialog.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
if(MotionEvent.ACTION_DOWN == ev.getAction())
{
Rect dialogBounds = new Rect();
dialog. getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// You have clicked the grey area
UiUtils.hideKeyboard2(getActivity());
return false; // stop activity closing
}
}
getActivity().dispatchTouchEvent(ev);
return false;
}
});
Спробуйте це. ви можете приховати клавіатуру, коли торкаєтесь зовні