16

そのため、ActionBarSherlock を使用していましたが、新しい ActionBarCompat に切り替えることにしました。ABS では、次の投稿で説明されている方法を使用して ActionBar を非表示にすることができました: アクティビティが作成される前にアクション バーを非表示にしてから再度表示する方法は?

ただし、ActionBarCompat を使用すると、API14 でアプリがクラッシュします。これは、メソッドに を宣言した場合でも、メソッドとして設定すると null が返されるandroid:windowActionBarためです。falsegetSupportActionBar()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();
}
4

4 に答える 4

19

私は同じ問題に行き詰まり、この奇妙な動作の理由を見つけたようです。サポートライブラリのソースを調べたところ、次のようになりました。

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とその子孫ActionBarDelegateHCActionBarActivityDelegateICSActionBarActivityJBがあり、実行中の android のバージョンに応じてそのうちの 1 つが選択されます。メソッドsupportRequestWindowFeatureは実際にはほとんどすべてで正常に機能しますが、そのActionBarActivityDelegateICSようにオーバーライドされます

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

したがって、変数mHasActionBarには影響しません。そのため、getSupportActionBar()null が返されます。

私たちはほとんどそこにいます。私は2つの異なる解決策にたどり着きました。

最初の方法

  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. この行をアクティビティのonCreateメソッドの前に配置しますgetSupportActionBar()

    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. このようなアクティビティのメソッドrequestFeature()を呼び出すonCreate

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

私は2番目の方法を使用しました。それで全部です。

于 2013-12-01T18:09:30.583 に答える
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>
于 2014-06-26T20:00:23.950 に答える
0

あなたのアクティビティは ActionBarActivity を拡張していますか? おそらくそうではなく、それが getActionbar() メソッドで実行されている理由です。

于 2013-09-20T14:37:59.623 に答える