ActionBarCompat: Hide ActionBar before activity is created (bug?)

后端 未结 4 803
故里飘歌
故里飘歌 2020-12-15 07:06

So I was using the ActionBarSherlock and decided to switch to the new ActionBarCompat. With ABS, hiding the ActionBar was possible using the way described in this post: How

相关标签:
4条回答
  • 2020-12-15 07:29

    Does your activity extends ActionBarActivity? Probably it doesn't and that's why it's running with the getActionbar() method.

    0 讨论(0)
  • 2020-12-15 07:36

    I got stuck with the same problem and, it seems to me, found a reason of this strange behavior. I looked through source of support library and got this:

    Appcompat checks a value of mHasActionBar variable before creating new action bar in 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();
        ...
    

    And we can change its value by calling supportRequestWindowFeature(int featureId) which is delegated by ActionBarActivity to a ActionBarActivityDelegate.

    There are base delegate class ActionBarDelegateBase and its descendants ActionBarDelegateHC, ActionBarActivityDelegateICS, ActionBarActivityJB, one of which is chosen according to a version of running android. And method supportRequestWindowFeature is actually works fine almost in all of them, but it's overridden in ActionBarActivityDelegateICS like that

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

    So it has no effect on the variable mHasActionBar, that's why getSupportActionBar() returns null.

    We almost there. I came to two different solutions.

    First way

    1. import source project of appcompat from git

    2. change overridden method in ActionBarActivityDelegateICS.java to something like this

      @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. place this line in activity's onCreate method before getSupportActionBar()

      supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
      

    Second way

    1. import project of appcompat from android SDK (which is with empty src directory)

    2. add this method to your activity

      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. call requestFeature() in onCreate method of your activity like this

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

    I used the second way. That's all.

    0 讨论(0)
  • 2020-12-15 07:45

    I don`t know if I understood exactly your question, but here I go.

    I think that you need to use both: getSupportActionBar() to old versions and getActionBar() to newest versions. It`s not a bug.

    You need to verify the device version before use the methods.

    I hope I was able to help.

    0 讨论(0)
  • 2020-12-15 07:48

    I use this to hide ActionBar in AppCompat: 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>
    
    0 讨论(0)
提交回复
热议问题