私は同じ問題に行き詰まり、この奇妙な動作の理由を見つけたようです。サポートライブラリのソースを調べたところ、次のようになりました。
Appcompat は、ActionBarActivityDelegatemHasActionBar
で新しいアクション バーを作成する前に、変数の値をチェックします。
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();
...
また、ActionBarActivityDelegatesupportRequestWindowFeature(int featureId)
に委任されたものを呼び出すことで、その値を変更できます。ActionBarActivity
ベース デリゲート クラスActionBarDelegateBase
とその子孫ActionBarDelegateHC
、ActionBarActivityDelegateICS
、ActionBarActivityJB
があり、実行中の android のバージョンに応じてそのうちの 1 つが選択されます。メソッドsupportRequestWindowFeature
は実際にはほとんどすべてで正常に機能しますが、そのActionBarActivityDelegateICS
ようにオーバーライドされます
@Override
public boolean supportRequestWindowFeature(int featureId) {
return mActivity.requestWindowFeature(featureId);
}
したがって、変数mHasActionBar
には影響しません。そのため、getSupportActionBar()
null が返されます。
私たちはほとんどそこにいます。私は2つの異なる解決策にたどり着きました。
最初の方法
gitから appcompat のソース プロジェクトをインポートする
オーバーライドされたメソッド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);
私は2番目の方法を使用しました。それで全部です。