所以我使用ActionBarSherlock并决定切换到新的ActionBarCompat。使用ABS,可以使用本文中描述的方式隐藏ActionBar: How to hide action bar before activity is created, and then show it again?
但是,使用ActionBarCompat,应用程序在API14上崩溃,因为当您将android:windowActionBar
设置为false
时,getSupportActionBar()
方法返回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();
}
答案 0 :(得分:19)
我遇到了同样的问题,在我看来,发现了这种奇怪行为的原因。我浏览了support library的来源并得到了这个:
中创建新操作栏之前,Appcompat会检查mHasActionBar
变量的值
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();
...
我们可以通过调用由supportRequestWindowFeature(int featureId)
委派给ActionBarActivityDelegate的ActionBarActivity
来更改其价值。
有基础委托类ActionBarDelegateBase
及其后代ActionBarDelegateHC
,ActionBarActivityDelegateICS
,ActionBarActivityJB
,其中一个是根据运行的android版本选择的。方法supportRequestWindowFeature
实际上几乎可以在所有方法中正常工作,但它在ActionBarActivityDelegateICS
中被覆盖了
@Override
public boolean supportRequestWindowFeature(int featureId) {
return mActivity.requestWindowFeature(featureId);
}
因此它对变量mHasActionBar
没有影响,这就是getSupportActionBar()
返回null的原因。
我们几乎在那里。我找到了两种不同的解决方案。
从git
将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;
}
在onCreate
getSupportActionBar()
方法中
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
从android SDK导入appcompat的项目(带有空的src目录)
将此方法添加到您的活动中
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);
}
}
在此活动的requestFeature()
方法中调用onCreate
if (Build.VERSION.SDK_INT >= 11) {
requestFeature();
}
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
我用第二种方式。就是这样。
答案 1 :(得分:5)
我用它来隐藏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>
答案 2 :(得分:0)
我不知道我是否完全明白你的问题,但我会去。
我认为您需要同时使用旧版本getSupportActionBar()
和最新版本getActionBar()
。这不是一个错误。
在使用这些方法之前,您需要验证设备版本。
我希望能够提供帮助。
答案 3 :(得分:0)
您的活动是否扩展了ActionBarActivity?可能它没有,这就是它使用getActionbar()方法运行的原因。