Ответ 1
Я застрял с той же проблемой и, как мне кажется, нашел причину этого странного поведения. Я просмотрел источник библиотеки поддержки и получил следующее:
Appcompat проверяет значение переменной mHasActionBar
перед созданием новой панели действий в 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();
...
И мы можем изменить его значение, вызвав supportRequestWindowFeature(int featureId)
, который делегирован ActionBarActivity
на ActionBarActivityDelegate.
Существует базовый класс делегата ActionBarDelegateBase
и его потомки ActionBarDelegateHC
, ActionBarActivityDelegateICS
, ActionBarActivityJB
, один из которых выбран в соответствии с версией бегущего андроида. И метод supportRequestWindowFeature
на самом деле работает отлично почти во всех из них, но он переопределяется в ActionBarActivityDelegateICS
как
@Override
public boolean supportRequestWindowFeature(int featureId) {
return mActivity.requestWindowFeature(featureId);
}
Таким образом, это не влияет на переменную mHasActionBar
, поэтому getSupportActionBar()
возвращает значение null.
Мы почти там. Я пришел к двум различным решениям.
Первый способ
-
импортировать исходный проект appcompat из 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);
Второй способ
-
импортировать проект appcompat из SDK android (с пустым каталогом 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);
Я использовал второй путь. Это все.