Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


ActionBarCompat: Ocultar ActionBar antes de crear la actividad (bug?)

Así que estaba usando el ActionBarSherlock y decidí cambiar a la nueva ActionBarCompat. Con ABS, ocultar la ActionBar fue posible utilizando la forma descrita en este post: ¿Cómo ocultar la barra de acción antes de que se cree la actividad, y luego mostrarla de nuevo?

Sin embargo, con ActionBarCompat la aplicación se bloquea en API14, porque cuando se establece android:windowActionBar como false el método getSupportActionBar() devuelve null, incluso si ha declarado getWindow().requestFeature(Window.FEATURE_ACTION_BAR); en el método onCreate() .

Lo curioso es que si llamas a getActionBar() , obtienes el objeto y todo funciona bien.

Así que, ¿es un error o estoy perdiendo algo? ¡Cualquier idea es bienvenida!


archivo styles.xml :

 <style name="Theme.MyApp" parent="@style/Theme.AppCompat.Light.DarkActionBar"> <item name="android:windowActionBar">false</item> <item name="android:windowTitleSize">0dp</item> </style> 

Archivo MyActivity.java :

 ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get the action bar feature. This feature is disabled by default into the theme // for specific reasons. getWindow().requestFeature(Window.FEATURE_ACTION_BAR); ... // By default the action bar is hidden. getSupportActionBar().hide(); } 

4 Solutions collect form web for “ActionBarCompat: Ocultar ActionBar antes de crear la actividad (bug?)”

Me quedé atascado con el mismo problema y, me parece, encontró una razón de este comportamiento extraño. Miré a través de la fuente de la biblioteca de apoyo y obtuve esto:

Appcompat comprueba un valor de la variable mHasActionBar antes de crear una nueva barra de acción en ActionBarActivityDelegate

 final ActionBar getSupportActionBar() { // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar // could change after onCreate if (mHasActionBar || mOverlayActionBar) { if (mActionBar == null) { mActionBar = createSupportActionBar(); ... 

Y podemos cambiar su valor llamando a supportRequestWindowFeature(int featureId) que es delegado por ActionBarActivity a un ActionBarActivityDelegate .

Hay una clase de delegado de base ActionBarDelegateBase y sus descendientes ActionBarDelegateHC , ActionBarActivityDelegateICS , ActionBarActivityJB , uno de los cuales se elige según una versión de ejecución de android. Y el método supportRequestWindowFeature es en realidad funciona bien casi en todos ellos, pero es sobreescrito en ActionBarActivityDelegateICS como ese

 @Override public boolean supportRequestWindowFeature(int featureId) { return mActivity.requestWindowFeature(featureId); } 

Así que no tiene ningún efecto sobre la variable mHasActionBar , por eso getSupportActionBar() devuelve null.

Casi estamos allí. He llegado a dos soluciones diferentes.

Primera manera

  1. import source project de appcompat desde git

  2. cambio método anulado en ActionBarActivityDelegateICS.java a algo como esto

     @Override public boolean supportRequestWindowFeature(int featureId) { boolean result = mActivity.requestWindowFeature(featureId); if (result) { switch (featureId) { case WindowCompat.FEATURE_ACTION_BAR: mHasActionBar = true; case WindowCompat.FEATURE_ACTION_BAR_OVERLAY: mOverlayActionBar = true; } } return result; } 
  3. coloque esta línea en el método onCreate la actividad antes de getSupportActionBar()

     supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR); 

Segundo camino

  1. proyecto de importación de appcompat desde android SDK (que es con directorio src vacío)

  2. agregue este método a su actividad

     private void requestFeature() { try { Field fieldImpl = ActionBarActivity.class.getDeclaredField("mImpl"); fieldImpl.setAccessible(true); Object impl = fieldImpl.get(this); Class<?> cls = Class.forName("android.support.v7.app.ActionBarActivityDelegate"); Field fieldHasActionBar = cls.getDeclaredField("mHasActionBar"); fieldHasActionBar.setAccessible(true); fieldHasActionBar.setBoolean(impl, true); } catch (NoSuchFieldException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } catch (IllegalAccessException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } catch (IllegalArgumentException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } catch (ClassNotFoundException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } } 
  3. requestFeature() en el método onCreate de su actividad como esta

     if (Build.VERSION.SDK_INT >= 11) { requestFeature(); } supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR); 

Utilicé el segundo camino. Eso es todo.

Utilizo esto para ocultar ActionBar en AppCompat: style.xml

 <style name="Theme.AppCompat.Light.NoActionBar" parent="@style/Theme.AppCompat.Light"> <item name="android:windowNoTitle">true</item> </style> 

AndroidManifest.xml:

 <activity android:name=".Splash" android:label="@string/title_activity_splash" android:theme="@style/Theme.AppCompat.Light.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 

No sé si he entendido exactamente su pregunta, pero aquí voy.

Creo que usted necesita usar ambos: getSupportActionBar() a versiones antiguas y getActionBar() a versiones más nuevas. No es un error.

Debe verificar la versión del dispositivo antes de utilizar los métodos.

Espero haber podido ayudar.

¿Su actividad amplía ActionBarActivity? Probablemente no lo hace y por eso está funcionando con el método getActionbar ().

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.