Ответ 1
Попробуйте установить setBackgroundDrawable
на PopupWindow
, который должен закрыть окно, если вы коснетесь его.
У меня есть PopupWindow в моей деятельности, вещь моя PopupWindow все еще показывает, даже когда я взаимодействую с моей деятельностью (скажем, прокруткой в моем списке). Я могу прокручивать список, и PopupWindow все еще существует.
То, что я хочу достичь, - это когда я касаюсь/прокручиваю/нажимаю/etc на экране, который не является PopupWindow, я хочу отклонить PopupWindow. Так же, как меню работает. Если вы вышли за пределы меню, меню будет отклонено.
Я пробовал setOutsideTouchable(true)
, но он не будет закрывать окно. Спасибо.
Попробуйте установить setBackgroundDrawable
на PopupWindow
, который должен закрыть окно, если вы коснетесь его.
Я обнаружил, что ни один из предоставленных ответов не работал у меня, кроме комментариев WareNinja о принятом ответе, и Марцин С., вероятно, также будет работать. Здесь часть, которая работает для меня:
myPopupWindow.setBackgroundDrawable(new BitmapDrawable());
myPopupWindow.setOutsideTouchable(true);
В качестве альтернативы:
myPopupWindow.setFocusable(true);
Не знаю, каковы различия, но исходный код ListPopupWindow на самом деле использует последний, когда для модальности установлено значение true с помощью setModal, поэтому разработчики Android считают это жизнеспособным подходом, и это только одна строка.
Я встретил те же проблемы и исправил его как ниже кодов. Это отлично работает для меня.
// Closes the popup window when touch outside.
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);
// Removes default background.
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
BTW. Не используйте устаревший конструктор BitmapDrawable, используйте этот новый ColorDrawable (android.R.color.transparent), чтобы заменить фон по умолчанию.
Удачи @. @
Я знаю это поздно, но я замечаю, что у людей все еще есть проблема со всплывающим окном. Я решил написать полностью рабочий пример, в котором вы можете закрыть всплывающее окно, коснувшись или щелкнув его или просто коснувшись самого окна. Для этого создайте новый класс PopupWindow и скопируйте этот код:
PopupWindow.class
public class PopupWindow extends android.widget.PopupWindow
{
Context ctx;
Button btnDismiss;
TextView lblText;
View popupView;
public PopupWindow(Context context)
{
super(context);
ctx = context;
popupView = LayoutInflater.from(context).inflate(R.layout.popup, null);
setContentView(popupView);
btnDismiss = (Button)popupView.findViewById(R.id.btn_dismiss);
lblText = (TextView)popupView.findViewById(R.id.text);
setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
// Closes the popup window when touch outside of it - when looses focus
setOutsideTouchable(true);
setFocusable(true);
// Removes default black background
setBackgroundDrawable(new BitmapDrawable());
btnDismiss.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
dismiss();
}});
// Closes the popup window when touch it
/* this.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
dismiss();
}
return true;
}
}); */
} // End constructor
// Attaches the view to its parent anchor-view at position x and y
public void show(View anchor, int x, int y)
{
showAtLocation(anchor, Gravity.CENTER, x, y);
}
}
Теперь создайте макет для всплывающего окна: popup.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:orientation="vertical"
android:padding="10dp" >
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:text="PopupWindow Example"
android:textColor="#000000"
android:textSize="17sp"
android:textStyle="italic" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<Button
android:id="@+id/btn_dismiss"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dismiss"
android:visibility="gone" />
<TextView
android:id="@+id/lbl_dismiss"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Touch outside of this box to dismiss"
android:textColor="#ffffff"
android:textStyle="bold" />
</FrameLayout>
В вашем основном действии создайте экземпляр класса PopupWindow:
final PopupWindow popupWindow = new PopupWindow(this);
popupWindow.show(findViewById(R.id.YOUR_MAIN_LAYOUT), 0, -250);
где YOUR_MAIN_LAYOUT - это макет текущей активности, в которой всплывающее окно всплывает
Спасибо за ответ @LunaKong и подтверждение @HourGlass. Я не хочу делать дублированный комментарий, но хочу сделать его четким и лаконичным.
// Closes the popup window when touch outside. This method was written informatively in Google docs.
mPopupWindow.setOutsideTouchable(true);
// Set focus true to prevent a touch event to go to a below view (main layout), which works like a dialog with 'cancel' property => Try it! And you will know what I mean.
mPopupWindow.setFocusable(true);
// Removes default background.
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Mttdat.
Обратите внимание, что для отмены с помощью popupWindow.setOutsideTouchable(true)
,
вам нужно сделать ширину и высоту wrap_content
, как показано ниже:
PopupWindow popupWindow = new PopupWindow(
G.layoutInflater.inflate(R.layout.lay_dialog_support, null, false),
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(view, Gravity.RIGHT, 0, 0);
При a ListPopupWindow
установите, чтобы окно отображалось как модальное.
mListPopupWindow.setModal(true);
Таким образом, щелчок за пределами ListPopupWindow
отклонит его.
mPopWindow.setFocusable(true);
Установите прозрачность окна:
PopupWindow.getBackground().setAlpha(0);
После установки фона в макете. Прекрасно работает.
@Предложение LunaKong работает как шарм.
Но настройка mPopupWindow.setFocusable(false). удаляет ненужное касание, необходимое для того, чтобы всплывающее окно исчезло.
Например: Предположим, есть всплывающее окно, видимое на экране, и вы собираетесь нажать кнопку. Итак, в этом случае (если mpopwindow.setFocusable(true)) при первом нажатии кнопки popupwindow будет уволен. Но вам нужно нажать еще раз, чтобы кнопка работала. если ** (mpopwindwo.setFocusable(ложь) ** одним нажатием кнопки отклонить всплывающее окно, а также нажать кнопку мыши. Надеюсь, поможет.
popupWindow.setTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
Он отключит PopupWindow, когда вы нажмете/коснитесь экрана. Убедитесь, что вы установили фокусировку true перед showAtLocation.
В некоторых случаях создание фокуса всплывающего окна нежелательно (например, вы можете не хотеть, чтобы он украл фокус с другого вида).
Альтернативный подход - использование сенсорного перехватчика:
popupWindow.setOutsideTouchable(true);
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
popupWindow.dismiss();
}
return false;
}
});
Используйте View popupView, чтобы закрыть popupWindow.
'popupView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupWindow.dismiss();
}
});
'Если вы используете это, вы также можете установить OnClickListener на любую кнопку внутри всплывающего окна
Вы можете использовать isOutsideTouchable
ИЛИ isFocusable
чтобы закрыть всплывающее окно при касании снаружи
popupWindow.isOutsideTouchable = true // dismiss popupwindow when touch outside
popupWindow.isFocusable = true // dismiss popupwindow when touch outside AND when press back button
Заметка
В настоящее время, после теста я вижу, setBackgroundDrawable
не помогает нам закрыть popupwindow
Если вы посмотрите на код для отклонения в PopupWindow
(PopupWindow->PopupDecorView->dispatchKeyEvent
и PopupWindow->PopupDecorView->onTouchEvent
). Вы увидите, что когда вы нажимаете кнопку "назад", они отклоняются на ACTION_UP
а когда касаются снаружи, они отклоняются на ACTION_UP
или ACTION_OUTSIDE