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>