Problemas al crear una ventana emergente en la actividad de Android

Estoy tratando de crear una ventana emergente que sólo aparece la primera vez que se inicia la aplicación. Quiero que muestre algún texto y tenga un botón para cerrar el popup. Sin embargo, tengo problemas para conseguir que el PopupWindow funcione. He intentado dos formas diferentes de hacerlo:

Primero tengo un archivo XML que declara el diseño del popup llamado popup.xml (un textview dentro de un linearlayout) y lo he agregado en el OnCreate () de mi actividad principal:

PopupWindow pw = new PopupWindow(findViewById(R.id.popup), 100, 100, true); pw.showAtLocation(findViewById(R.id.main), Gravity.CENTER, 0, 0); 

En segundo lugar hice exactamente lo mismo con este código:

 final LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); PopupWindow pw = new PopupWindow(inflater.inflate(R.layout.popup, (ViewGroup) findViewById(R.layout.main) ), 100, 100, true); pw.showAtLocation(findViewById(R.id.main_page_layout), Gravity.CENTER, 0, 0); 

El primero lanza una excepción NullPointerException y el segundo lanza una excepción BadTokenException y dice que "no se puede agregar el nulo de la ventana-token no es válido"

¿Qué demonios estoy haciendo mal? Soy muy novato así que por favor, tenga paciencia conmigo.

Para evitar la excepción BadTokenException, debe diferir la visualización de la ventana emergente hasta que se llamen todos los métodos del ciclo de vida (-> se muestra la ventana de actividad):

  findViewById(R.id.main_page_layout).post(new Runnable() { public void run() { pw.showAtLocation(findViewById(R.id.main_page_layout), Gravity.CENTER, 0, 0); } }); 

La solución proporcionada por Kordzik no funcionará si inicia dos actividades consecutivas:

 startActivity(ActivityWithPopup.class); startActivity(ActivityThatShouldBeAboveTheActivivtyWithPopup.class); 

Si agrega popup de esa manera en un caso como este, obtendrá el mismo bloqueo porque ActivityWithPopup no se conectará a Window en este caso.

La soledad más universal es onAttachedToWindow y onDetachedFromWindow .

Y también no hay necesidad de postDelayed (Runnable, 100). Porque este 100 milis no garantiza nada

 @Override public void onAttachedToWindow() { super.onAttachedToWindow(); Log.d(TAG, "onAttachedToWindow"); showPopup(); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); Log.d(TAG, "onDetachedFromWindow"); popup.dismiss(); } 

Me pareció que la respuesta aceptada no funcionaba para mí. Todavía recibí el error de token malo .. Así que acabo de llamar a la runnable de un controlador con el retraso como tal ..

 new Handler().postDelayed(new Runnable() { public void run() { showPopup(); } }, 100); 

Hay dos situaciones en las que podría ocurrir esta excepción. Uno es mencionado por kordzik. Otro escenario se menciona aquí: http://blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/

Asegúrese de manejar ambos

La solución es configurar el modo de hilado para dialogar como se muestra a continuación:

 android:spinnerMode="dialog" 

o

 Spinner(Context context, int mode) tnxs RamallahDroid 

Mira esto.

Dependiendo del caso de uso, para los tipos de pop-up para mostrar un mensaje, la configuración del tipo emergente a TYPE_TOAST utilizando setWindowLayoutType() evita el problema, ya que este tipo de pop-up no depende de la actividad subyacente.

Editar: Uno de los efectos secundarios: no hay interacción en la ventana emergente para API <= 18, ya que los eventos aptos para tocar / enfocables serían eliminados por el sistema. ( http://www.jianshu.com/p/634cd056b90c )

Termino usando TYPE_PHONE (ya que la aplicación tiene el permiso SYSTEM_ALERT_WINDOW, de lo contrario esto no funcionará también).

Compruebe que findViewById devuelve algo – puede ser que lo llame demasiado pronto, antes de que se construya el diseño

También es posible que desee publicar salida logcat para las excepciones que está recibiendo

También puede intentar utilizar esta comprobación:

  public void showPopupProgress (){ new Handler().post(new Runnable() { @Override public void run() { if (getWindow().getDecorView().getWindowVisibility() == View.GONE) { showPopupProgress(); return; } popup.showAtLocation(.....); } }); } 

Puede comprobar la vista de raíz si tiene el token. Puede obtener el diseño padre definido de su actividad xml, mRootView

 if (mRootView != null && mRootView.getWindowToken() != null) { popupWindow.showAtLocation(); } 

Si muestra un PopupWindow en otro PopupWindow, no utilice la vista en el primer POP, use la vista principal de origen.

 pop.showAtLocation(parentView, ... ); 

Puede especificar el desplazamiento y para contabilizar la barra de estado desde el método pw.showAtLocation

  • ¿Cómo mostrar el PopupWindow siempre encima del botón (vista)?
  • PopupWindow de Android / Diálogo
  • ListPopupWindow no obedeciendo WRAP_CONTENT width spec
  • Android: setText () para TextView en PopupWindow no funciona
  • Error de hilandero en la ventana emergente cuando hago clic
  • Cómo desenfocar / atenuar una actividad cuando se muestra una ventana emergente en android
  • ListPopupWindow: getWindowVisibleDisplayFrame (Rect) null excepción
  • Android PopupWindow showAsDropDown () no funciona correctamente
  • PopupWindow en una coordenada específica sin vista de anclaje
  • Android: ¿Cómo arrastrar (mover) PopupWindow?
  • Android popupwindow está por encima del teclado virtual
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.