您的位置:首页 > 其它

ActionBar最近学习整理之一:显示选项内容及菜单项

2013-08-14 22:06 78 查看
前段时间需要对GB的项目版本升级到ICS和JB,需要使用的ActionBar构建新的标题栏,琢磨了一个多月,算入门了。整理下部分内容,以供交流学习~
typedef ActionBar AB

ActionBar是啥

Google自3.0后新推出的标题栏UI组件,一种能够统一标题栏内容显示方式的窗口属性,其实就是包括一系列选项内容的标题栏、导航模式、交互菜单项等,Using the action bar offers your users a familiar interface across applications
that the system gracefully adapts for different screen configurations。还是为了用户体验和设计的一致性。
具体来说,ActionBar为用户提供了一系列的信息,如该Activity的图标文字,一些常用的菜单选项,溢出菜单及搜索栏的使用显示,用户自定义的标题栏布局等,Google官网给出了一个例图如下:



这张例图中包含了1】应用图标、2】AcationBar菜单项 3】AB溢出菜单项,下面还可以看到Tab标签,这些都可以在ActionBar在显示出来。ActionBar是在API11以后才引入的,如果想在早期版本中使用该组件,可以导入android.suppor.v7.app.actionbar。参考http://developer.android.com/tools/support-library/setup.html设置库。对于targetSdkVersion在11或者以上的应用来说,默认主题"Theme.Holo"使用了ActionBar,如果不想使用该组件,可以设置主题为"Theme.Holo.NoActionBar"。
Actionbar包括的组件信息较为繁杂,如显示选项内容,也就是由选项开关控制的一些基本布局;ActionItem,布置在标题栏上的菜单按钮,以及ActionProvider、ActionView,OverFlowMenu,Navigation Tabs等,本文主要整理最常用且直观的“显示选项内容“(名字我自己起的,其实就是较为常用的标题栏内容)和ActionItem的内容。

ActionBar显示选项有哪些

最常用的AB内容包括哪些?接触比较多的是显示选项内容,以APIDEMO中的ActionBarDisplayOptions为例,介绍说明不同选项内容的类型和注意事项。



从上图能看出,一个标准AB的显示选项从左到右包括up箭头、icon、title、customView,Logo在该图中没有显示,就是一个类似于品牌的宽点的icon。
up箭头,主要用于返回上个activity,默认点击是没用反应的,可以在选项菜单处理函数中以“android.R.id.home”进行标示,up箭头的返回和Back按键还是有区别的,前者以当前Activity所在的栈序列为基础,Back按钮在按照屏幕显示的历史顺序进行后退,这点区别主要发生在模块交互时。举个例子,比如用户在短信模块进行操作,想要添加一张图片,调用了图库模块的图片选择界面,而恰巧该图库选择界面是个singleTask(仅仅是恰巧,不保证实际情况就是),也就是说图片选择界面存在于另一个已经存在的图库栈,在点击up箭头后就会回到图库栈的上一个activity,而点击Back按钮则回到短信模块。大部分情况下Up箭头和Back还是行为一致的。
对于up导航和back导航有一个比较重要的区别点,就是up导航强调栈内逻辑,对于任何一个应用栈都存在一个主activity,官方文档叫做Topmost screen,就是该应用的主界面,往往是应用进入后的第一个界面,比如短信模块的是收件箱界面,联系人模块的是已存联系人列表,Topmost界面是不应该有up导航标签的,因为up标签的存在就是为了方便用户返回到Topmost界面,up标签主要用于一个模块内的导航,导航的目的就是Topmost界面,当然如果离Topmost界面较远,也可以导航到上一个activity,但仍然在该模块内。back键导航主要根据出现时间上的逆序,可以跨模块。详细的导航模式设计在官网上有着清晰的解释,因为本文主要讲Actionbar,感兴趣的童鞋请参考http://developer.android.com/design/patterns/navigation.html
up箭头的显示和消失受DISPLAY_HOME_AS_UP控制,该标志位定义在ActionBar.java抽象类中。
Icon图标,也就是在AndroidManifest中定义的图标,和logo是”不可兼得“的关系,如果使用logo,则icon被取代,受DISPLAY_USE_LOGO开关控制,这个图标官方建议用Logo取代,Log会显示的稍微宽些,个人觉得无所谓,就是一个你想显示的app图片。通常是和Launcer界面的应用图标一样的,定义在AndroidManifest.xml中的android:icon/android:logo选项中。显示开关标志为DISPALY_SHOW_HOME。up箭头和icon图标就是传说中的Home区域,源代码是action_bar_home.java ,使用的是HomeView类布局。
<view xmlns:android="http://schemas.android.com/apk/res/android"
class="com.android.internal.widget.ActionBarView$HomeView"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<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" />
<ImageView android:id="@android:id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dip"
android:layout_marginTop="@android:dimen/action_bar_icon_vertical_padding"
android:layout_marginBottom="@android:dimen/action_bar_icon_vertical_padding"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
</view>

Title,本例中的Title有点特殊,显示的是路径,当然可以显示任何字符串,配合subTitle显示效果更加清晰。Title类似于早起的标题栏Title,只不过Google给写好了风格样式,咱们只需要调用API即可,显示开关标识为DISPLAY_SHOW_TITLE。该位置的源码是action_bar_title_layout_item.java。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingEnd="8dip"
android:enabled="false">

<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" />

<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:orientation="vertical">
<TextView android:id="@+id/action_bar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end" />
<TextView android:id="@+id/action_bar_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/action_bar_subtitle_top_margin"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>

CustomView是用户自定义的区域,该部分区域显示在前述内容之外的空白的区域,可以像普通layout一样布局到该区域中,主要用于显示个性化试图界面,当然,你也可以把上述四个部分内容清除,自定义全部ActionBar的空间,类似于以前版本的requestWindowFeature(Window.FEATURE_CUSTOM_TITLE),你可以自由布局自己的Custom,可以把背景设置成透明色,以保持和默认标题栏背景色的一致。对于那些复杂的需要控制焦点走向的标题栏布局,自定义的比较多。自定义视图的显示开关标识为DISPLAY_SHOW_CUSTOM。

ActionBar显示选项内容API

一坨坨API看着比较心烦,整理下,和选项内容相关的貌似不多,而且还比较直观,暗爽:
public abstract void setDisplayUseLogoEnabled(boolean useLogo); ----------是否使用logo而不是icon
public abstract void setDisplayShowHomeEnabled(boolean showHome); --------是否显示Home区域的icon,注意,logo和icon二者不可兼得,且该函数不控制up箭头的显示(视觉上)
public abstract void setDisplayHomeAsUpEnabled(boolean showHomeAsUp);--------是否打开up箭头显示开关,PS:关闭时up箭头不显示,打开时up箭头一定显示吗?你可以把其它选项内容都关闭试下
public abstract void setDisplayShowTitleEnabled(boolean showTitle);----------是否显示Title区域
public abstract void setDisplayShowCustomEnabled(boolean showCustom);----------是否显示自定义视图
好吧,还是有点繁杂,public abstract void setDisplayOptions(int options, int mask)看起来挺简单,看api介绍比较蒙,研究了一下实现,觉得这个比较好,参数里,options 表示的是最终想要设置的结果,mask表示为了达到这个结果我需要改变的开关项,举个例子,setDisplayOptions(DISPLAY_SHOW_HOME,
DISPLAY_SHOW_HOME | DISPLAY_USE_LOGO),我想改变两个开关,DISPLAY_SHOW_HOME和DISPLAY_USE_LOGO,我想达到的结果:只有DISPLAY_SHOW_HOME开关打开,另一个关闭,那其他的开关呢,保持默认。如果我想改变所有的开关到一个结果呢,public abstract void setDisplayOptions(int options)。
还有些setTitle、setIcon之类的就不聊了,实现在ActionbarImpl.java中。

ActionBar上的菜单项——ActionItem

标题栏的右侧,通常会放置一些会经常用到的菜单项,官方将这种菜单项命名为ActionItem,而且建议对于这些菜单项要有分级策略,对于类似于搜索、新建、打开等和当前上下文环境连接较为紧密的菜单项放到直接显示的位置,也就是标题栏的右侧,对于类似共享、帮助、设置等联系不是那么紧密的,建议放到溢出菜单项里。ActionItem的个数不能超过4个,放在ActionItem的菜单原则上可以分成以下三个类型,常用,比如短信模块的编辑新短信;重要,比如摄像头模块的设置;典型,比如新浪微博的刷新,而有些是原则上不要放到ActionItem中的,诸如帮助、设置、应用信息等。



[align=left] 典型的ActionItem布局如上图,最右边的是溢出菜单按钮,点击后会以类似下拉菜单的形式弹出溢出菜单,这是对于像平板一样没有实体菜单按钮的处理方式。对于有按键菜单的手机来说,上述布局的溢出菜单项就是普通菜单项,按下菜单按钮显示普通菜单项,不会像上图一样显示最右那个图标。关于ActionItem和普通选项菜单的不同,需要从产生过程上加以区别。在较早版本的系统中,当用户启动一个Activity时,菜单内容并没有被系统解析,当用户按下实体菜单键时,onCreateOptionMenu才被调用,进而完成选项菜单的解析和显示流程。3.0以后引入ActionBar,要求Activity在启动时就有获取选项菜单信息,并将其中被设置为ActionItem的菜单显示在标题栏中,于是onCreateOptionMenu的调用时间前移了,Activity被创建时即被调用,而每次点击实体菜单键时,系统通过调用onPrepareOptionMenu完成更新,如果开发过程中需更新菜单(包括普通选项菜单和ActionItem),invalidoptionMenu可以用来调用onPrepareOptionMenu,完成即时菜单项更新。在此之前,我们先要在onCreateOptionMenu中完成MenuInflter过程,以便在Activity启动时正常显示ActionItem。[/align]
这样看来,显示在Actionbar上的菜单项仅仅是一种特殊化的选项菜单罢了,如何定义某个菜单项为ActionItem呢,android:showAsAction="ifRoom|withText|always|never|collapseActionView",在菜单布局中或者代码中设置该属性,其中ifRoom
: 有空间就设置;WithText:如果空间充足ActionItem显示文本如上图,空间不足可以不显示;always设置为ActionItem,建议不超过两项ActionItem,never:不设置。最后一项collapseActionView和Actionview相关,以后提到相关内容时在说。
对于ActionItem而言,android:title属性相当重要,这个属性解释了该菜单项的作用,在溢出菜单下会显示title,如果由于空间原因没有显示该title而仅显示菜单项图标,长按ActionItem也会显示该项信息。
ActionItem可以认为是比较特殊的一类菜单项,放置在Actionbar中,处理函数同普通选项菜单一致,官网建议能作为ActionItem的菜单项需具有全局作用域,意思是需要针对对整个Activity层面的功能,而不是仅仅控制其中的某个窗口,举个例子,类似于平板电脑中的设置布局,左侧是设置项、右侧是设置信息,能作为你Activity的ActionItem必须是针对整个设置界面的,而不是某一项设置信息。

ActionBar上的分割菜单项

很简单的一种分割形式,在使用较为紧张的宽度布局设备时,比如普通非大屏手机,把ActionItem显示在屏幕底部的一种布局,如果宽度不是很紧张,比如手机横屏了,则正常布局到上方标题栏。好吧,之所以还写在这,就是给自己提个醒,不要看到这样的UI就去自己设计布局,框架层已经做好的事情,在AndroidManifest的<activity>节点设置android:uiOptions="splitActionBarWhenNarrow"即可。

小结

ActionBar的显示选项内容和ActionItem,是AB入门的基础知识,通过官方文档和分析源码实现,可以少走不少弯路,接触时间不长,理解有限,在项目中遇到了一些和本文相关的问题及解决方案,会在下一篇AB博文中整理分享~~

~版权所有~转载请声明~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: