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>
