ActionBarCompat:在创build活动之前隐藏ActionBar(bug?)

所以我使用的ActionBarSherlock,并决定切换到新的ActionBarCompat。 使用ABS,隐藏ActionBar是可能的使用在这篇文章中描述的方式: 如何在创build活动之前隐藏操作栏,然后再显示它?

但是,与ActionBarCompat应用程序在API14上崩溃,因为当您将android:windowActionBar设置为falsegetSupportActionBar()方法返回null,即使您已经声明了getWindow().requestFeature(Window.FEATURE_ACTION_BAR); 进入onCreate()方法。

有趣的是,如果你调用getActionBar()来取代对象,一切正常。

那么,这是一个错误还是我错过了什么? 任何想法都欢迎!


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> 

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

Solutions Collecting From Web of "ActionBarCompat:在创build活动之前隐藏ActionBar(bug?)"

我陷入了同样的问题,在我看来,find了这个奇怪行为的原因。 我通过支持库的来源,并得到这个:

在ActionBarActivityDelegate中创build新的操作栏之前,Appcompat会检查mHasActionBarvariables的值

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

我们可以通过调用由ActionBarActivity委托给ActionBarActivity supportRequestWindowFeature(int featureId)来改变它的值。

有基类委托类ActionBarDelegateBase及其后代ActionBarDelegateHCActionBarActivityDelegateICSActionBarActivityJB ,其中之一是根据运行的android版本select的。 而方法supportRequestWindowFeature实际上几乎在所有这些工作正常,但它在ActionBarActivityDelegateICS这样重写

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

所以它对variablesmHasActionBar没有影响,这就是getSupportActionBar()返回null的原因。

我们几乎在那里。 我来到两个不同的解决scheme。

第一种方式

  1. 从git导入appcompat的源码项目

  2. ActionBarActivityDelegateICS.java中将重写的方法更改为像这样

     @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. 将此行放置在getSupportActionBar()之前的activity的onCreate方法中

     supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR); 

第二种方式

  1. 从android SDK中导入appcompat项目(这是空的src目录)

  2. 将此方法添加到您的活动中

     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. 在你的activity的onCreate方法中调用requestFeature()方法

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

我用第二种方法。 就这样。

我用这个来隐藏AppCompat中的ActionBar: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> 

我不知道我是否明白你的问题,但我在这里。

我认为你需要同时使用: getSupportActionBar()到旧版本和getActionBar()到最新版本。 这不是一个错误。

在使用这些方法之前,您需要validation设备版本。

我希望我能够帮助。

你的活动是否扩展了ActionBarActivity? 可能它不会,这就是为什么它使用getActionbar()方法运行。