ActionBar en un DialogFragment

En la aplicación Calendario de mi Galaxy Tab 10.1, al crear un nuevo evento, aparece un cuadro de diálogo con los botones Hecho y Cancelar en el área de barra de título / barra de acción.

Introduzca aquí la descripción de la imagen

Me gustaría implementar esto en mi aplicación. He intentado usar setHasOptionsMenu(true) además de sobreescribir onCreateOptionsMenu en mi subclase DialogFragment , pero mis elementos de acción no aparecen. También he intentado llamar a getDialog().getActionBar() desde dentro onCreateView pero siempre devuelve null .

Puedo conseguir este funcionamiento si comienzo una Activity más bien que demostrando un diálogo pero eso ocupa la pantalla entera. ¿Hay una manera estándar de hacer esto usando un DialogFragment ?

Utilizando la idea de un post de grupo de google que era capaz de sacarlo de estilo de una actividad. Usted querría modificar la altura y el ancho a un tamaño "dinámico" de su preferencia. A continuación, establezca los botones de ActionBar que desee

 <style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog"> <item name="android:windowIsFloating">false</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowSoftInputMode">stateAlwaysHidden</item> <item name="android:windowActionModeOverlay">true</item> <item name="android:windowIsTranslucent">true</item> </style> 

 public static void showAsPopup(Activity activity) { //To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND); LayoutParams params = activity.getWindow().getAttributes(); params.height = 850; //fixed height params.width = 850; //fixed width params.alpha = 1.0f; params.dimAmount = 0.5f; activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); setContentView(R.layout.activity_main); } 

Si está utilizando ActionBarSherlock, declare el tema como se indica a continuación:

 <style name="PopupTheme" parent="Theme.Sherlock"> <item name="android:windowFrame">@null</item> <item name="android:windowIsFloating">false</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <item name="android:windowSoftInputMode">stateAlwaysHidden</item> <item name="android:windowActionModeOverlay">true</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowCloseOnTouchOutside">true</item> <item name="android:windowIsTranslucent">true</item> <item name="windowContentOverlay">@null</item> </style> 

Y, inicializar una SherlockActivity con PopupTheme según la respuesta de Luke Sleeman .

 private void showAsPopup(SherlockActivity activity) { //To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest //activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); // NO NEED to call this line. activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND); LayoutParams params = activity.getWindow().getAttributes(); params.alpha = 1.0f; params.dimAmount = 0.5f; activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); // This sets the window size, while working around the IllegalStateException thrown by ActionBarView activity.getWindow().setLayout(width,height); } 

Resultado:

Introduzca aquí la descripción de la imagen

Tuve algunos problemas para implementar las soluciones sugeridas de StrikeForceZero y Luke Sleeman, así que quería contribuir con mi experiencia. Estoy seguro de que hay algo que me falta, así que la retroalimentación sería muy apreciada.

Lo que hice fue lo siguiente:

  1. Crear un estilo utilizando el PopupTheme proporcionado, recto copiar / pegar:

     <style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog"> <item name="android:windowIsFloating">false</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowSoftInputMode">stateAlwaysHidden</item> <item name="android:windowActionModeOverlay">true</item> <item name="android:windowIsTranslucent">true</item> </style> 
  2. Agregue el método showAsPopup () como un método en el fragmento que abriría el fragmento de diálogo falso, copiar / pegar directamente:

     private void showAsPopup(Activity activity) { //To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND); LayoutParams params = activity.getWindow().getAttributes(); params.alpha = 1.0f; params.dimAmount = 0f; activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); // This sets the window size, while working around the IllegalStateException thrown by ActionBarView activity.getWindow().setLayout(850,850); } 
  3. Cree una instancia de la nueva actividad utilizando una llamada new () simple y, a continuación, pase al método showAsPopup ():

     DialogTestActivity test = new DialogTestActivity(); showAsPopup(test); 
  4. Para el propósito de la prueba (sólo estaba tratando de confirmar que podía abrir una actividad que se presenta como un diálogo con una barra de acción) He utilizado una prueba muy simple, robado directamente desde la vista del botón demo api (para el archivo de diseño , Ver buttons_1.xml en las demostraciones de api):

     public class DialogTestActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.buttons_test); } } 

Desafortunadamente, cada vez que intenté esto, consigo una excepción del puntero nulo no especificada en la primera llamada, activity.requestWindowFeature (Window.FEATURE_ACTION_BAR);

 04-29 16:39:05.361: W/System.err(15134): java.lang.NullPointerException 04-29 16:39:05.361: W/System.err(15134): at android.app.Activity.requestWindowFeature(Activity.java:3244) 04-29 16:39:05.371: W/System.err(15134): at packagenameremovedforlegalreasons.classname.showAsPopup(classname.java:602) 04-29 16:39:05.371: W/System.err(15134): at packagenameremovedforlegalreasons.classname.onMapLongClick(classname.java:595) 04-29 16:39:05.371: W/System.err(15134): at com.google.android.gms.maps.GoogleMap$5.onMapLongClick(Unknown Source) 04-29 16:39:05.371: W/System.err(15134): at com.google.android.gms.internal.k$a.onTransact(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at android.os.Binder.transact(Binder.java:310) 04-29 16:39:05.381: W/System.err(15134): at com.google.android.gms.maps.internal.IOnMapLongClickListener$Stub$Proxy.onMapLongClick(IOnMapLongClickListener.java:93) 04-29 16:39:05.381: W/System.err(15134): at maps.isa(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at maps.yvd(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at maps.y.bf.onLongPress(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at maps.dvonLongPress(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at maps.dhc(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at maps.dhc(Unknown Source) 04-29 16:39:05.381: W/System.err(15134): at maps.djhandleMessage(Unknown Source) 04-29 16:39:05.391: W/System.err(15134): at android.os.Handler.dispatchMessage(Handler.java:99) 04-29 16:39:05.391: W/System.err(15134): at android.os.Looper.loop(Looper.java:137) 04-29 16:39:05.391: W/System.err(15134): at android.app.ActivityThread.main(ActivityThread.java:5041) 04-29 16:39:05.391: W/System.err(15134): at java.lang.reflect.Method.invokeNative(Native Method) 04-29 16:39:05.391: W/System.err(15134): at java.lang.reflect.Method.invoke(Method.java:511) 04-29 16:39:05.391: W/System.err(15134): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 04-29 16:39:05.391: W/System.err(15134): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 04-29 16:39:05.391: W/System.err(15134): at dalvik.system.NativeStart.main(Native Method) 

Como se puede ver en el rastreo de la pila, el comportamiento previsto es abrir la ventana en una pulsación larga en una instancia de GoogleMap (utilizando los MapFragments de la API 2). Así que mi primer pensamiento fue que había un problema de intentar abrir desde un fragmento, así que pasé la llamada de vuelta a la actividad de propietario. El mismo error, igual no hay información adicional.

Mi mejor conjetura en este punto fue que una nueva () llamada no instanciar suficientemente la clase / vista para hacer llamadas para modificar su vista. Resulta que esto parece ser al menos algo cierto, ya que migrar el código de modificación de vista en la actividad y simplemente abrir la actividad de la manera normal funciona:

Actividad de llamada:

  public void openMapDialog() { Intent intent = new Intent(this, DialogTestActivity.class); startActivity(intent); } 

Nuevo código de clase:

  public class DialogTestActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // From: https://stackoverflow.com/questions/11425020/actionbar-in-a-dialogfragment this.requestWindowFeature(Window.FEATURE_ACTION_BAR); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND); LayoutParams params = this.getWindow().getAttributes(); params.alpha = 1.0f; params.dimAmount = 0f; this.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); // This sets the window size, while working around the IllegalStateException thrown by ActionBarView this.getWindow().setLayout(600,600); setContentView(R.layout.buttons_test); } } 

Así que supongo que el punto de mí publicar todo esto es aclarar que si quieres hacer lo que sugieren los carteles anteriores, no puedes simplemente new () una actividad y llamar a showAsPopup (). Esta puede ser mi inexperiencia con Android mostrando a través, pero aunque esto parece un poco obvio, también parece natural interpretar showAsPopup () como ser llamado por la vista actual, no la vista que se está creando, como usted está pasando en la instancia de actividad (Que sería sólo esto si se suponía que debía hacerse en onCreate () como acabé haciendo).

Así que si la intención es llamar a showAsPopup () en la actividad de creación y no la actividad creada , no es obvio cómo obtener la instancia de Activity que es modificable antes de llamarse onCreate (). El problema es que no se puede llamar a las cosas como requestWindowFeature () después de setContentView () se llama ( ejemplo ), que es un problema ya que normalmente se llama en onCreate ().

Una vez más, si hay una manera fácil / mejor de hacer esto, yo apreciaría mucho la regeneración. Esperemos que esto sea útil para las personas que quieren usar este enfoque.

He pasado una increíble cantidad de tiempo jugando con esto. La respuesta aceptada funciona en un nexo galaxia 7 (Android 4.2), pero falla en una galaxia samsung SIII (Android 4.1) y una pestaña galaxia Samsung 10.2 (Android 4.0), con la siguiente excepción:

 IllegalStateException: ActionBarView can only be used with android:layout_width="match_parent" (or fill_parent) 

Esto es causado por código en ActionBarView.onMeasure (int, int) que comprueba para asegurarse de que el diseño esté configurado como match_parent. La solución correcta es en su lugar establecer el ancho de la ventana a través de setLayout en lugar de utilizar el setAttributes.

Esta es una versión fija de showAsPopup () que funciona en todos los dispositivos que he probado en:

 private void showAsPopup(Activity activity) { //To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND); LayoutParams params = activity.getWindow().getAttributes(); params.alpha = 1.0f; params.dimAmount = 0f; activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); // This sets the window size, while working around the IllegalStateException thrown by ActionBarView activity.getWindow().setLayout(850,850); } 

Para mayor satisfacción, aquí está de nuevo el PopupTheme:

 <style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog"> <item name="android:windowIsFloating">false</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowSoftInputMode">stateAlwaysHidden</item> <item name="android:windowActionModeOverlay">true</item> <item name="android:windowIsTranslucent">true</item> </style> 

Como Veeti implícito, es posible que desee probar la implementación de una actividad con un tema de diálogo. En el manifiesto de Android:

 <activity android:name=".YourActivity" android:theme="@android:style/Theme.Dialog </activity> 

Esperemos que eso ayude.

Probablemente no soy tan experimentado en eso, pero usaría una actividad, agregaría elementos de barras de acción y luego:

<activity android:name=".YourActivity" android:theme="@android:style/Theme.Holo.Light.Dialog" />

¡Espero que ayude!

Sé que no es una respuesta real, pero por encima de soluciones parecen tan poco elegante que uno podría pensar que sería más fácil evitar la barra de acción en absoluto, como heredar el tema de diálogo de algo con .noActionBar y luego crear vista en la parte superior de su panel Que imita barra de acción, al menos de esta manera todo se queda en xlm.

He encontrado una manera agradable de hacerlo, usando setCustomTitle en el constructor del alertDialog para el DialogFragment (también posible en el alertDialog sí mismo).

 public Dialog onCreateDialog(final Bundle savedInstanceState) { final AlertDialog.Builder builder = new AlertDialog.Builder(activity,...); final Toolbar toolbar = (Toolbar) inflater.inflate(R.layout.dialog_app_filter_toolbar, null, false); // <= prepare toolbar and dialog here return builder.create(); } 

Y el resultado (de mi aplicación ):

Introduzca aquí la descripción de la imagen

Introduzca aquí la descripción de la imagen

Si no desea utilizar AlertDialog, todavía puede poner una barra de herramientas en su diseño del diálogo y utilizarlo.

  • ¿Es posible iniciar un DialogFragment desde una preferencia en una preferenciaActivity?
  • Diálogo personalizado con setMultiChoiceItems
  • Cómo descartar correctamente un DialogFragment?
  • Android DialogFragment Redimensionamiento automático
  • Cómo mostrar un DialogFragment de un controlador
  • OnCancelListener no se llama en DialogFragment
  • ¿Por qué Android O falla con "no pertenece a este FragmentManager!"
  • Diálogo de soporte personalizado El texto del fragmento es el color incorrecto
  • ListView no se actualiza hasta que el teclado esté oculto
  • Argumento DialogFragment y excepción nullpointer
  • Cómo quitar el título de DialogFragment?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.