Wyskakujące okno Android

Mam wyskakujące okno wyświetlane po kliknięciu elementu na liście aktywności. Problem w tym, że tylny klucz go nie zamyka. Próbowałem złapać klucz Tylny w mojej aktywności na liście, ale nie rejestruje go...następnie próbowałem zarejestrować onkeylistener do widoku, który przechodzę do mojego wyskakującego okna. TAK:

pop.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            boolean res=false;
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
                // do something on back.
                Log.e("keydown","back");
                if (pw.isShowing()) {
                    Log.e("keydown","pw showing");
                    pw.dismiss();
                    res = true;
                }
            } else {
                res = false;
            }
            return res;
        }
    });

Który jest przekazywany do wyskakującego okienka jak to:

pw = new PopupWindow(
       pop, 
       240, 
       70, 
       true);
Ale ten słuchacz też nie strzela. Możesz mi pomóc? Skończyły mi się pomysły:)
Author: Rich Schuler, 2010-06-26

9 answers

Dzieje się tak dlatego, że wyskakujące okno nie odpowiada na zdarzenia onTouch lub onKey, chyba że ma tło, które != null. Zobacz kod, który napisałem , aby w tym pomóc. W podstawowym przypadku można wywołać PopupWindow#setBackgroundDrawable(new BitmapDrawable()), aby zmusić go do działania zgodnie z oczekiwaniami. Nie będziesz potrzebował własnego słuchacza onKey. Może być również konieczne wywołanie PopupWindow#setOutsideTouchable(true), jeśli chcesz, aby zniknął, gdy użytkownik kliknie poza granicami okna.

Rozszerzona odpowiedź ezoteryczna:

The reason the background nie może być null z powodu tego, co dzieje się w PopupWindow#preparePopup. Jeśli wykryje background != null, utworzy instancję PopupViewContainer i wywoła setBackgroundDrawable na to i umieści w niej widok zawartości. PopupViewContainer jest w zasadzie FrameLayout, który nasłuchuje zdarzeń dotykowych i zdarzenia KeyEvent.KEYCODE_BACK, aby zamknąć okno. Jeśli background = = null, to nic z tego nie robi i po prostu używa widoku zawartości. Możesz, jako alternatywę dla zależności od PopupWindow, aby sobie z tym poradzić, rozszerzyć swój root ViewGroup, aby zachowywać się tak, jak chcesz.

 146
Author: Rich Schuler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-26 04:31:44

Wykonaj zgodnie z poniższym, działa dobrze:

PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, true);
pw.setBackgroundDrawable(new BitmapDrawable());
pw.setOutsideTouchable(true);
pw.showAsDropDown(btnSelectWeight);
 35
Author: Sunil Parmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 02:19:18

Dla nowych projektów lepiej używać

popupWindow.setBackgroundDrawable(new ColorDrawable());

Zamiast

popupWindow.setBackgroundDrawable(new BitmapDrawable());
Ponieważ BitmapDrawable jest przestarzały. W tym przypadku jest to lepsze niż ShapeDrawable. Zauważyłem, że gdy PopupWindow jest prostokątem z zaokrąglonymi rogami, ShapeDrawable wypełnia rogi czarnym.
 6
Author: CoolMind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-26 14:31:32

Bardzo prostym rozwiązaniem jest napisanie pw.setFocusable (true), ale prawdopodobnie nie chcesz tego robić, ponieważ wtedy MapActivity nie obsłuży zdarzeń dotykowych.

Lepszym rozwiązaniem jest nadpisanie klawisza Wstecz, np. tak:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    // Override back button
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (pw.isShowing()) {
            pw.dismiss();
            return false;
        }
    }
    return super.onKeyDown(keyCode, event);
} 
Powodzenia!
 5
Author: Vanja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-08 13:49:42

Dla nowych wyszukiwarek , ponieważ tworzenie new BitmapDrawable nie jest teraz dozwolone (The constructor BitmapDrawable() is deprecated), więc musisz zmienić go na new ShapeDrawable(), aby zmienić:

pw.setBackgroundDrawable(new BitmapDrawable());

Do:

pw.setBackgroundDrawable(new ShapeDrawable());

A cała praca będzie jak:

PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, true);
pw.setOutsideTouchable(true);
pw.setBackgroundDrawable(new ShapeDrawable());
pw.setTouchInterceptor(new OnTouchListener() { // or whatever you want
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            if(event.getAction() == MotionEvent.ACTION_OUTSIDE) // here I want to close the pw when clicking outside it but at all this is just an example of how it works and you can implement the onTouch() or the onKey() you want
            {
               pw.dismiss();
               return true;
            }
            return false;
        }

});
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
 4
Author: Muhammed Refaat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-22 09:12:01

Po prostu użyj tego

mPopupWindow.setBackgroundDrawable(new BitmapDrawable(null,""));

Który nie jest przestarzały. unikałbym new ShapeDrawable (), ponieważ będzie renderować powoli, gdy próbuje narysować kształt, gdy ekran musi być przerysowany.

 4
Author: j2emanue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-27 02:46:36

Mam nadzieję, że to będzie pomoc dla ciebie

 pw.setTouchInterceptor(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                pw.dismiss();
            }
            return true;
        }
    });
 3
Author: Dwivedi Ji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-18 07:25:12

Musisz dodać setBackgroundDrawable(new BitmapDrawable()) do swojego PopupWindow.

 1
Author: Carl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-13 02:01:41
    private void initPopupWindow() {  
    // TODO Auto-generated method stub  

    View view = getLayoutInflater().inflate(R.layout.main_choice, null);  

    ListView main_menu_listview = (ListView) view.findViewById(R.id.main_menu_listview);  

    ShowMainChoice madapter = new ShowMainChoice(context);
    main_menu_listview.setAdapter(madapter);

    int width = (int)getWindowManager().getDefaultDisplay().getWidth()/2;
    popupWindow = new PopupWindow(view, width,WindowManager.LayoutParams.WRAP_CONTENT);  
    popupWindow.setBackgroundDrawable(new BitmapDrawable());//this is important,如果缺少这句将导致其他任何控件及监听都得不到响应
    popupWindow.setOutsideTouchable(true);
    popupWindow.setFocusable(true);

    main_menu_listview.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
            // TODO Auto-generated method stub

            Log.e("++++++>", arg2+"");

        }
    });
}

Ten problem jest popupwindow底层 pop pop pop pop。。。。.Powodzenia

 0
Author: AlexChu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 02:48:19