Despido de la ventana emergente de Android

Tengo una ventana emergente que se muestra cuando hago clic en un elemento en la actividad de mi lista. El problema es que la tecla de retroceso no lo cierra. Intenté capturar la tecla de retroceso en mi actividad de lista pero no la registra … luego traté de registrar un onkeylistener en la vista que estoy pasando a mi ventana emergente. Me gusta esto:

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; } }); 

que se pasa a una ventana emergente como esta:

 pw = new PopupWindow( pop, 240, 70, true); 

Pero ese oyente no dispara tampoco. ¿Me puedes ayudar? Estoy sin ideas 🙂

Esto se debe a que la ventana emergente no responde a los eventos onTouch u onKey a menos que tenga un fondo que! = Null. Echa un vistazo al código que escribí para ayudarte con esto. En el caso básico, puede llamar a PopupWindow#setBackgroundDrawable(new BitmapDrawable()) para forzarlo a actuar de la manera que espera. No necesitarás tu propio oyente onKey. También es posible que necesite llamar a PopupWindow#setOutsideTouchable(true) si desea que desaparezca cuando el usuario haga clic fuera de los límites de la ventana.

Respuesta esotérica extendida:

La razón por la que el fondo no puede ser nulo se debe a lo que sucede en PopupWindow#preparePopup . Si detecta background != null PopupViewContainer , crea una instancia de PopupViewContainer y llama a setBackgroundDrawable sobre eso y pone su vista de contenido en ella. PopupViewContainer es básicamente un FrameLayout que escucha eventos táctiles y el evento KeyEvent.KEYCODE_BACK para cerrar la ventana. Si background == null, no hace nada de eso y solo usa su vista de contenido. Como alternativa a depender de PopupWindow para manejar eso, puede ampliar su ViewGroup raíz para que se comporte de la manera que desee.

Hazlo según sigue funciona bien:

 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); 

Para nuevos proyectos, es mejor usar

 popupWindow.setBackgroundDrawable(new ColorDrawable()); 

en lugar de

 popupWindow.setBackgroundDrawable(new BitmapDrawable()); 

como BitmapDrawable está en desuso. Además, es mejor que ShapeDrawable en este caso. Noté que cuando PopupWindow es un rectángulo con esquinas redondeadas, ShapeDrawable llena las esquinas con negro.

Una solución realmente simple es escribir pw.setFocusable (verdadero), pero probablemente no desee hacer esto porque entonces MapActivity no manejará eventos táctiles.

Una mejor solución es anular la tecla de retroceso, por ejemplo, de esta manera:

 @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); } 

¡Buena suerte!

Para los nuevos buscadores , como la creación de un new BitmapDrawable no está permitido ahora ( The constructor BitmapDrawable() is deprecated ), por lo que debe cambiarlo a un new ShapeDrawable() , para que pueda cambiar:

 pw.setBackgroundDrawable(new BitmapDrawable()); 

A :

 pw.setBackgroundDrawable(new ShapeDrawable()); 

Y todo el trabajo será como:

 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); 

solo usa esto

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

que no está en desuso Evitaría que ShapeDrawable () nuevo se renderice lentamente, ya que intenta dibujar una forma cuando la pantalla necesita volver a dibujarse.

Espero que esto sea de ayuda para ti

  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; } }); 

necesita agregar setBackgroundDrawable(new BitmapDrawable()) para su PopupWindow .

  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+""); } }); } 

Este problema es popupwindow 底层 的 消息 机制 的 的, 因为 的 的 的 因为. Buena suerte