Mam PopupWindow w moim działaniu, chodzi o to, że moje PopupWindow nadal wyświetla się, nawet gdy wchodzę w interakcję z moją aktywnością (powiedzmy przewijanie mojej listy). Mogę przewijać moją listę, a PopupWindow nadal tam jest.
To, co chcę osiągnąć, to kiedy dotykam / przewijam / klikam / etc na ekranie, który nie jest PopupWindow, chcę odrzucić PopupWindow. Tak jak działa menu. Jeśli kliknąłeś poza menu, menu zostanie odrzucone.
Próbowałem, setOutsideTouchable(true)
ale to nie zamknie okna. Dzięki.
android
popupwindow
android-menu
wieśniak
źródło
źródło
BitmapDrawable()
jest pozbawiony praw. UżyjColorDrawable()
zamiast tego.Okazało się, że żadna z udzielonych odpowiedzi nie zadziałała dla mnie, z wyjątkiem komentarza WareNinja dotyczącego zaakceptowanej odpowiedzi, a Marcin S. prawdopodobnie również zadziała. Oto część, która działa dla mnie:
myPopupWindow.setBackgroundDrawable(new BitmapDrawable()); myPopupWindow.setOutsideTouchable(true);
Alternatywnie:
myPopupWindow.setFocusable(true);
Nie jestem pewien, jakie są różnice, ale kod źródłowy ListPopupWindow faktycznie używa tego drugiego, gdy jego modalność jest ustawiona na true za pomocą setModal, więc przynajmniej programiści Androida uważają to za wykonalne podejście i jest to tylko jedna linia.
źródło
setFocusable
, musimy dwukrotnie kliknąć przycisk (w miejscu, w którym przycisk znajduje się poza wyskakującym okienkiem), gdzie tak jak w pierwszej metodzie działa dobrze :)BitmapDrawable()
jest pozbawiony praw. UżyjColorDrawable()
zamiast tego.Napotkałem te same problemy i naprawiłem to, jak poniżej kody. U mnie działa dobrze.
// Closes the popup window when touch outside. mPopupWindow.setOutsideTouchable(true); mPopupWindow.setFocusable(true); // Removes default background. mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
BTW, nie używaj przestarzałego konstruktora BitmapDrawable, użyj tego nowego ColorDrawable (android.R.color.transparent) aby zastąpić domyślne tło.
Baw się dobrze@.@
źródło
Wiem, że jest późno, ale zauważam, że ludzie nadal mają problem z wyskakującym okienkiem. Postanowiłem napisać w pełni działający przykład, w którym możesz zamknąć wyskakujące okienko, dotykając lub klikając poza nim lub po prostu dotykając samego okna. Aby to zrobić, utwórz nową klasę PopupWindow i skopiuj ten kod:
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); } }
Teraz utwórz układ dla wyskakującego okienka: 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>
W swoim głównym działaniu utwórz instancję klasy PopupWindow:
final PopupWindow popupWindow = new PopupWindow(this); popupWindow.show(findViewById(R.id.YOUR_MAIN_LAYOUT), 0, -250);
gdzie YOUR_MAIN_LAYOUT jest układem bieżącego działania, w którym pojawi się popupWindow
źródło
Dzięki za odpowiedź @ LunaKong i potwierdzenie @ HourGlass. Nie chcę powtarzać komentarza, chcę tylko, aby był jasny i zwięzły.
// Closes the popup window when touch outside. This method was written informatively in Google's 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.
źródło
Aby
ListPopupWindow
ustawić okno jako modalne, gdy jest wyświetlane.mListPopupWindow.setModal(true);
W ten sposób kliknięcie poza obszarem
ListPopupWindow
woli go odrzuci.źródło
mListPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
, aby zapobiec kolidowaniu wyskakującego okienka z klawiaturą ekranową.Zwróć uwagę, że aby anulować za pomocą
popupWindow.setOutsideTouchable(true)
, musisz ustawić szerokość i wysokośćwrap_content
jak w poniższym kodzie: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);
źródło
popupWindow.setTouchable(true); popupWindow.setFocusable(true); popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
Po kliknięciu / dotknięciu ekranu, okno PopupWindow zostanie odrzucone. Upewnij się, że ustawiłeś fokus na true przed showAtLocation.
źródło
Możesz użyć
isOutsideTouchable
OR,isFocusable
aby zamknąć wyskakujące okienko, gdy dotkniesz na zewnątrzpopupWindow.isOutsideTouchable = true // dismiss popupwindow when touch outside popupWindow.isFocusable = true // dismiss popupwindow when touch outside AND when press back button
Uwaga
Obecnie po teście widzę,
setBackgroundDrawable
że nie pomaga nam w zamykaniu popupwindowJeśli spojrzysz na kod zwolnienia w
PopupWindow
(PopupWindow->PopupDecorView->dispatchKeyEvent
iPopupWindow->PopupDecorView->onTouchEvent
). Zobaczysz, że po naciśnięciu przycisku Wstecz zwalniają,ACTION_UP
a gdy dotykają na zewnątrz, zwalniają naACTION_UP
lubACTION_OUTSIDE
źródło
mPopWindow.setFocusable(true);
źródło
@LunaKong sugestia działa jak urok.
Ale konfigurowanie mPopupWindow.setFocusable (false). usuwa niepotrzebne dotknięcie wymagane do zniknięcia wyskakującego okienka.
Na przykład: Rozważmy, że na ekranie jest widoczne wyskakujące okienko i masz zamiar kliknąć przycisk. Więc w tym przypadku (jeśli mpopwindow.setFocusable (true)) przy pierwszym kliknięciu przycisku popupwindow zostanie odrzucone. Ale musisz kliknąć ponownie, aby przycisk działał. if ** (mpopwindwo.setFocusable (false) ** pojedyncze kliknięcie przycisku powoduje zamknięcie wyskakującego okienka i kliknięcie przycisku. Mam nadzieję, że to pomoże.
źródło
Ustaw przezroczyste tło okna:
PopupWindow.getBackground().setAlpha(0);
Po ustawieniu tła w układzie. Działa w porządku.
źródło
W niektórych przypadkach ustawianie fokusu na wyskakującym okienku nie jest pożądane (np. Możesz nie chcieć, aby kraść fokus z innego widoku).
Alternatywnym podejściem jest użycie przechwytywacza dotyku:
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; } });
źródło
Jeśli to wyskakujące okno jest inną czynnością i zmniejszyłeś jego rozmiar do pierwotnego ekranu i chcesz włączyć lub wyłączyć obszar zewnętrzny. Możesz po prostu włączyć lub wyłączyć obszar zewnętrzny za pomocą tego kodu:
włączyć:
YourActivity.this.setFinishOnTouchOutside(true);
wyłączyć:
YourActivity.this.setFinishOnTouchOutside(false);
źródło
Użyj Wyświetl popupView, aby odrzucić popupWindow
`popupView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { popupWindow.dismiss(); } });
`Jeśli tego używasz, możesz także ustawić funkcję OnClickListener na dowolny przycisk w oknie popupWindow
źródło