actionbar-displayOptions 屬性分析


displayOptions 這個屬性主要是控制這actionbar 上返回按鈕、標題等的顯示。它作為 actionBarStyle 的一個item,如下

 <style name="ActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
     <item name="android:displayOptions">showCustom|disableHome|showTitle|homeAsUp|</item>
 </style>

然后我們可以從 ActionBarView這個類中看到它的使用

setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT));

 

我們通過查詢源碼

frameworks/base/core/res/res/values/attrs.xml

可以發現這條屬性可以使用的成員如下

  <attr name="displayOptions">
            <flag name="none" value="0" />
            <flag name="useLogo" value="0x1" />
            <flag name="showHome" value="0x2" />
            <flag name="homeAsUp" value="0x4" />
            <flag name="showTitle" value="0x8" />
            <flag name="showCustom" value="0x10" />
            <flag name="disableHome" value="0x20" />
   </attr>

它們對應的代碼中的數值如下

                     
            ActionBar.DISPLAY_USE_LOGO |
            ActionBar.DISPLAY_SHOW_HOME |
            ActionBar.DISPLAY_HOME_AS_UP |
            ActionBar.DISPLAY_SHOW_TITLE |            
            ActionBar.DISPLAY_SHOW_CUSTOM | 
//disableHome 代碼中未看到 
//這個是設置是否 action_bar_title 雙行顯示                  
            ActionBar.DISPLAY_TITLE_MULTIPLE_LINES;     

 

 

 

 

下面我們就來研究下,這幾個屬性到底是什么作用

直接看demo

actionbar style

<style name="ActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
     <item name="android:displayOptions">showCustom|disableHome|showTitle|homeAsUp|useLogo|showHome</item>
</style>


我們發現,actionbar上面就顯示了三項。這三項分別是(從左到右)

homeAsUp-返回箭頭

showHome-圖標

showTitle-標題

其他沒有顯示的三項(接下來會研究)

useLogo-未知

showCustom-未知

disableHome-未知

我們去ActionBarView這個類中去尋找答案

1.showCustom

我們找到如下關鍵代碼

 public void setCustomView(View view) {
        final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
        if (showCustom) {
            ActionBarTransition.beginDelayedTransition(this);
        }    
        if (mCustomNavView != null && showCustom) {
            removeView(mCustomNavView);
        }    
        mCustomNavView = view;
        if (mCustomNavView != null && showCustom) {
            addView(mCustomNavView);
        }    
    }    

很明顯,這個屬性控制的是custoView的顯示問題

2.disableHome

 這個屬性具體有什么作用,暫時還沒有發現。在framework下搜索這個屬性也沒有找到具體使用的地方。

3.useLogo

還是從framework下尋找答案。我們從actionBarView中看到如下代碼

 if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { 
         final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0;
         mHomeLayout.setIcon(logoVis ? mLogo : mIcon);
  }    

所以說,它的作用其實跟showHome是差不多的,它就是從manifest里面讀取icon,然后在activity中顯示出來

 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:logo="@drawable/ic_person_add_24dp"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

此外,我們還能看到如下代碼

  final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
            final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
            final boolean titleUp = !showHome && homeAsUp;
            mHomeLayout.setShowIcon(showHome);



 public void setShowIcon(boolean showIcon) {
            mIconView.setVisibility(showIcon ? VISIBLE : GONE);
        }

 

我們知道,showHome 是總開關。只有它跟useLogo 同時存在的時候,才能顯示logo

 看如下效果

 

我們既然知道了這幾個屬性的意義,那么我們如何改改他們的樣式呢?這就需要我們去繼續看它們的代碼實現了。


還是在actionBarView中尋找答案

1.看到如下方法

public void setDisplayOptions(int options) {
    ......
}

我們還能從WindowDecorActionBar 中看到另一個相同的方法

public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
    ......
}

這兩個方法分析如下

直接看如下代碼

  public void removeBackButton() {
        if (mActionBar == null) {
            return;
        }   
        // Remove the back button but continue showing an icon.
        final int mask = ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME;
        mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME, mask);
        mActivity.getActionBar().setHomeButtonEnabled(false);
    }   
/* Vanzo:zhangshuli on: Fri, 17 Apr 2015 18:15:31 +0800
 */
    public void setBackButtonEnable(boolean enable) {
        if (mActionBar == null) {
            return;
        }   
        mActivity.getActionBar().setHomeButtonEnabled(enable);
    }   
// End of Vanzo: zhangshuli

    public void setBackButton() {
        if (mActionBar == null) {
            return;
        }   
        // Show home as up, and show an icon.
        final int mask = ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME;
        mActionBar.setDisplayOptions(mask, mask);
        mActivity.getActionBar().setHomeButtonEnabled(true);
    }   

上面代碼中

mActionBar.setDisplayOptions(mask, mask);

就是用來設置home按鈕顯示的,它的具體用法如下

(1)如果只有一個參數,那么它就是直接設定顯示項,

如,

int options = DISPLAY_SHOW_HOME | DISPLAY_USE_LOGO;
setDisplayOptions(options);

那么,actionbar就會顯示home跟log按鈕,也就是,里面添加了誰,誰就顯示

(2)如果有兩個參數的話

int options = ActionBar.DISPLAY_SHOW_TITLE |ActionBar.DISPLAY_SHOW_HOME ;

int mask = ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM;

getSupportActionBar().setDisplayOptions(options, mask);

如上代碼,這時候actionbar會顯示home 跟title,其他的不會顯示

也就是只有當options在mask中被設置才能被顯示,也就是設置為true。

2.單獨設置上面某個屬性顯示與否

從WindowDecorActionBar 能看到如下方法

單獨設置某項顯示方法如下

getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayShowCustomEnabled(true);
getActionBar().setDisplayShowHomeEnabled(true);
getActionBar().setDisplayShowTitleEnabled(true);
getActionBar().setDisplayUseLogoEnabled(true);

3.設置各個按鈕是否可點擊狀態

//它好像可以控制home等的點擊狀態
getActionBar().setHomeButtonEnabled(true);

 這個方法實現如下

private void setHomeButtonEnabled(boolean enable, boolean recordState) {
        if (recordState) {
            mWasHomeEnabled = enable;
        }    

        if (mExpandedActionView != null) {
            // There's an action view currently showing and we want to keep the state
            // configured for the action view at the moment. If we needed to record the
            // new state for later we will have done so above.
            return;
        }    

        mUpGoerFive.setEnabled(enable);
        mUpGoerFive.setFocusable(enable);
        // Make sure the home button has an accurate content description for accessibility.
        updateHomeAccessibility(enable);
    }    
  mUpGoerFive = (ViewGroup) inflater.inflate(
                com.android.internal.R.layout.action_bar_up_container, this, false);
        mHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);

很清楚就知道了,它控制的其實是homeAsUp 跟home兩個圖標的顯示問題

現在我們已經知道了它們的顯示跟隱藏,那么我們通過什么方式來更改它們的圖標呢。

仍然從代碼中找答案

 
//設置home圖標
public void setIcon(Drawable icon) {}
//設置logo圖標
public void setLogo(Drawable logo) {}
//設置homeAsUp圖標
public void setUpIndicator(Drawable d) {}
//設置title
public void setTitle(CharSequence title) {}
//設置subtitle
public void setSubtitle(CharSequence subtitle) {}

如何在xml中更改呢

<!-- 更改logo 跟icon-->
<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:logo="@drawable/action_mode_search_normal_white_p"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

更改homeAsUp

看up按鈕在framework中的布局

<!-- 更改homeAsUp-->

 <ImageView android:id="@android:id/up"
               android:src="?android:attr/homeAsUpIndicator"
               android:layout_gravity="center_vertical|start"
               android:visibility="gone"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginEnd="-8dip" />

所以我們可以在theme中修改它的圖標

<item name="homeAsUpIndicator">@android:drawable/ic_ab_back_funui</item>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM