ActionBar 小节
2014年6月28日 星期六
ActionBar是一种在Android 3.0(API 11)之后新增的导航栏功能,标识了用户当前操作界面的位置,并提供了额外的用户动作,界面导航等功能,为Android移动设备提供了全局同意的UI界面,并且ActionBar还可以自动适应各种不同大小的屏幕。ActionBar是3.0之后出现的控件,取代了之前的menu,显示在标题栏位置如下图:
上图是一个包含App icon,两个action view和一个overflow的按钮。
如果想在2.X的版本里使用ActionBar的话则需要引入Support Library 库。 3.0之前的使用不在此说明。
添加与移除Action Bar
从Android 3.0开始,Action Bar被包含在所有的使用Theme.Holo主题的Activity中。 默认的情况下项目会自动将App的theme为Theme.Holo,所以ActionBar默认的情况下都是显示出来的。
移除ActionBar,通常有两种方式:配置文件:
将activity的theme指定成Theme.Holo.NoActionbar
在Activity中代码调用
ActionBar actionBar = getActionBar();
actionBar.hide();
将ActionBar隐藏,或actionBar.show()显示
二. 修改Action Bar的图标,标题等
1 是应用的图标或logo,左侧类似于back返回键
2 是当前Action Bar的tittle
3 是 Action menu 相当于普通的button,可以监听点击事件
4 是 Action overflow, 也是menu,只是隐藏了而已
默认的情况下,系统会使用<application>或者<activity>中icon属性指定的图标作为ActionBar的图标。如果我们想要使用另外一张图片来作为ActionBar图标,可在<application>或者<activity>中设置logo属性。Tittle (label)同上可以在activity中修改。
当然,也可以在代码中设置相关参数。如下:
ActionBar actionBar = getActionBar();
/* 设置左侧那个箭头的显隐 ,对应 ActionBar.DISPLAY_HOME_AS_UP*/
actionBar.setDisplayHomeAsUpEnabled(true);//显
/* 修改Action Bar 应用图标 */
actionBar.setLogo(R.drawable.icon);
/* 当没有设置 logo的时候,icon如果有的话就起作用了 */
actionBar.setIcon(R.drawable.account_current);
/* 修改Action Bar tittle */
actionBar.setTitle("Action Bar");
/* 设置 Action Bar tittle 的显隐 ,ActionBar.DISPLAY_SHOW_TITLE*/
actionBar.setDisplayShowTitleEnabled(false);//隐
/* 设置 logo的显隐 */
actionBar.setDisplayUseLogoEnabled(true);//显
/* 设置应用图标显隐,对应Id:android.R.id.home ,ActionBar.DISPLAY_SHOW_HOME*/
actionBar.setDisplayShowHomeEnabled(false);//隐
/* 使自定义的普通View能在title栏显示,即 actionBar.setCustomView能起作用,对应
ActionBar.DISPLAY_SHOW_CUSTOM */
actionBar.setDisplayShowCustomEnabled(true) //显
注:其中setHomeButtonEnabled和setDisplayShowHomeEnabled共同起作用,如果setHomeButtonEnabled
3. 添加Action menu按钮
1> 添加的menu会显示在action bar 上,由于屏幕空间问题,多余的按钮会隐藏在overflow里面,点击一下overflow就能弹出。
当应用启动activity的时候就会调用onCreateOptionsMenu()方法加载所有的Action按钮。在此使用布局文件加载进去,也可以使用代码。
布局main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_add"
android:icon="@android:drawable/ic_menu_add"
android:showAsAction="always"
android:title="Add">
</item>
<item
android:id="@+id/action_delete"
android:icon="@android:drawable/ic_menu_delete"
android:showAsAction="always"
android:title="Delete"/>
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:showAsAction="never"
android:title="search"/>
</menu>
public boolean onCreateOptionsMenu(Menu menu) {
/* 代码动态加载 */
// menu.add(0, 0, 0, "menu1");
// menu.add(0,1,1,"menu2");
/* 使用资源文件加载 */
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
这里我们通过三个<item>标签定义了三个Action按钮。<item>标签中又有一些属性,其中id是该Action按钮的唯一标识符,icon用于指定该按钮的图标,title用于指定该按钮可能显示的文字(在图标能显示的情况下,通常不会显示文字),showAsAction则指定了该按钮显示的位置,主要有以下几种值可选:always表示永远显示在ActionBar中,如果屏幕空间不够则无法显示,ifRoom表示屏幕空间够的情况下显示在ActionBar中,不够的话就显示在overflow中,never则表示永远显示在overflow中。
• 当ActionBar中的剩余空间不足的时候,如果Action按钮指定的showAsAction属性是ifRoom的话,该Action按钮就会出现在overflow当中,此时就只有title能够显示了。
• 如果Action按钮在ActionBar中显示,用户可能通过长按该Action按钮方式来查看到title的内容
2> 响应action menu的点击事件
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add:
Toast.makeText(this, "add", Toast.LENGTH_SHORT).show();
break;
case R.id.action_delete:
Toast.makeText(this, "delete", Toast.LENGTH_SHORT).show();
break;
case R.id.action_search:
Toast.makeText(this, "search", Toast.LENGTH_SHORT).show();
default:
break;
}
return super.onOptionsItemSelected(item);
}
4. 分离式 Action menu(splitActionBar)
当Android API >14 时,可使用“分离式”Action menu。当你启用它时,在屏幕的底部会显示一个独立的横条,用于Activity在窄屏设备上显示所有的Action menu,同时把导航条和标题元素留在顶部。
启用Action bar分离模式,只需要在配置文件中设置即可。在Activity或Application中设置参数 android:uiOptions="splitActionBarWhenNarrow"
5. 应用图标的使用
应用图标对应ID:android.R.id.home,顾名思义,可以通过其执行:
1> 返回应用程序的主“Activity”或其他Activity
2> 返回应用程序栈内上级页面导航
当用户点触这个图标时,系统会调用Activity带有android.R.id.home ID的onOptionsItemSelected()方法。
如果使用应用程序图标的响应来返回主Activity,那么在Intent对象中包括FLAG_ACTIVITY_CLEAR_TOP标识。使用这个标识,如果你要启动的Activity在当前任务已经存在,那么,堆栈中在这个Activity之上的所有Activity都将销毁,并把此Activity显示给用户。
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
一般情况下,ActionBar导航和Back键的功能貌似是一样的,只需finish()或者System(0)一下就可退出当前Activity了,但还是有一些区别的。
1. back键的功能就是后退到前一界面或状态,或者取消。
2. up键导航层次关系
6. 添加Action menu 可视窗。
如果菜单资源中的一个项目声明一个操作视窗,既可以使用android:actionLayout属性也可以使用android:actionViewClass属性来分别指定一个布局资源或要使用的可视构件类。例如“搜索”。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
</menu>
android:showAsAction属性也可包含“collapseActionView”属性值,声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。可以通过Activity的onKeyUp()方法监听按键事件,如果你需要更新Activity,你也可以定义一个OnActionExpandListener事件监听展开事件
7. 添加一个Action Provider
可以给这个菜单项提供一个一处菜单的文本标题,以防止它会在overflow当中出现。它提供了它在溢出菜单中显示时所能执行的默认操作,但是Activity(Fragment)也能通过处理来自onOptionItemSelected()回调方法的点击事件来重写这个默认操作。如果你不在这个回调方法中处理点击事件,那么Provider会接收onPerformdefaultAction()回调来处理事件。如果是Provider提供的子菜单,那么Activity就不能接收。例如:使用ShareActionProvider类作为Action Provider。
要添加ShareActionProvider对象,只需要简单地设置android:actionProviderClass属性为android:widget.ShareActionprovider就可以了。唯一要做的就是通过Intent来定义出你想分享哪些东西了,我们只需要在onCreateOptionsMenu()中调用MenuItem的getActionProvider()方法来得到该ShareActionProvider对象,再通过setShareIntent()方法去选择构建出什么样的一个Intent就可以了。代码如下:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
MenuItem shareItem = menu.findItem(R.id.action_share);
ShareActionProvider provider = (ShareActionProvider) shareItem.getActionProvider();
provider.setShareIntent(getDefaultIntent());
......
return super.onCreateOptionsMenu(menu);
}
private Intent getDefaultIntent() {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
return intent;
}
通过getDefaultIntent()方法来构建了一个Intent,该Intent表示会将所有可以共享图片的应用都列出来,如图:
这个ShareActionProvider点击之后也是可以展开的,有点类似于overflow的意思,他们就是Action Provider的子菜单。除了使用ShareActionProvider之外,我们也可以自定义一个Action Provider,重写方法onPrepareSubMenu()方法。
三. 添加导航Tabs
在手机屏幕空间不足的情况下,Tabs和ActionBar按钮则会分为两行显示。
如何使用ActionBar提供的Tab功能?
实现ActionBar的TabListener接口,这个接口提供了Tab事件的各种回调,比如当用户点击了一个Tab时,你就可以进行Tab操作。
public class MyTabListener <T extends Fragment> implements TabListener {
private Fragment mFragment;
private Activity mActivity;
private Class<T> mClass;
public MyTabListener(Activity activity,Class<T> classTemp) {
this.mActivity = activity;
this.mClass = classTemp;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
if(mFragment == null){
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(R.id.fragment_container,mFragment);
}
ft.attach(mFragment);
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
if(mFragment != null){
ft.detach(mFragment);
}
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
为每一个你想添加的Tab创建一个ActionBar.Tab的实例,并且调用setTabListener()方法来设置ActionBar.TabListener。除此之外还可设置Tab标签
Tab tabOne = actionBar.newTab().setText("Tab1").setTabListener(new MyTabListener<FragmentOne>(MainActivity.this, FragmentOne.class));
最后调用ActionBar的addTab()方法将创建好的Tab添加到ActionBar中。
actionBar.addTab(tabOne);
四. 自定义ActionBar样式
Android内置了几个Activity主题中包含了“dark”或“light”的ActionBar样式,同时我们也可继承这些主题进行自己的定制。
Android中有两个最基本的Activity主题可以用于指定ActionBar颜色:
Theme.Holo 深色的主题
Theme.Holo.Light 浅色的主题
你可以将主题应用于整个应用程序,也可以运用于单个的Activity。如果只想让ActionBar使用深色调的主题,而Activity的内容部分仍然使用浅色的主题,可以声明Theme.Holo.Light.DarkActionBar这个主题。
自定义ActionBar
使用ActionBarStyle属性,并将这个属性指向了我们自定义的样式,例如:
<!-- 自定义ActionBar样式,例如:背景,title字体样式等
android:displayOptions:显示title,logo等选项;
android:backgroundStacked:设置ActionBar Tab 背景色-->
<style name="MBACustomActionBarStyle" parent="@android:style/Widget.Holo.ActionBar">
<item name="android:background">@drawable/zhiku_top_img</item>
<item name="android:titleTextStyle">@style/MBAActionBarTitleStyle</item>
<item name="android:backgroundStacked">#d27026</item>
<item name="android:displayOptions">showHome</item>
</style>
<!-- 设置 ActionBar title样式,例如:大小,颜色,字样式等 -->
<style name="MBAActionBarTitleStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">#535F6F</item>
<item name="android:textSize">30sp</item>
<item name="android:textStyle">italic</item>
</style>
<!-- 设置ActionBar Tab的标签大小,颜色等 -->
<style name="MBAActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText">
<item name="android:textColor">#FF0000</item>
</style>
将自定义的样式,引入到自定义的主题上。
<style name="MBACustomAppTheme" parent="android:Theme.Holo">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
<item name="android:actionBarStyle">@style/MBACustomActionBarStyle</item>
<item name="android:actionMenuTextAppearance">@style/ActionBarMenuTextStytle</item>
<item name="android:actionBarTabTextStyle">@style/MBAActionBarTabText</item>
</style>
五. 自定义Tab Indicator 。
分辨Tab选中项的标识,一条横线。需要重写actionBartabStyle属性,重写background属性即可,且必须是一个drawable文件。有四种状态:选中未按下,选中按下,未选中未按下,未选中按下。那么新建indicator.xml文件。
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/tab_unselected" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="@drawable/tab_selected" />
<item android:state_selected="false"
android:state_pressed="true"
android:drawable="@drawable/tab_unselected_pressed" />
<item android:state_selected="true"
android:state_pressed="true"
android:drawable="@drawable/tab_selected_pressed" />
</selector>
那么引进此文件,自定义TabView样式
<style name="MBAActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">@drawable/actionbar_tab_indicator</item>
</style>
使用android:actionBarTabStyle属性引入在主题定义中。
总结:
至于为什么要引 parent项,就类似于继承关系一样。个人建议:在定义某一种样式时,需要引入的要引用相应的父级样式。
例如:
ActionBarStyle,———> “@android:style/……… .ActionBar”
ActionBarTitle ———> @android:style/TextAppearance……..…ActionBar.Title
等,具体原因具体分析实践。另外,对于API的level也要有相应的注意定义有所不同。
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!--
自定义主题:
1. android:actionBarStyle:设置顶部标题栏那一带的属性,使用style类型引用。
2. android:actionMenuTextAppearance :设置menu标签的文字大小,stytle等
3. android:actionMenuTextColor :设置ActionBar上的文字颜色
4. android:actionButtonStyle :设置ActionBar上每个按钮的stytle,主要是背景色等(不包括文字),一个menu item相当于一个Button
5. android:actionBarSplitStyle :设置split类型的ActionBar stytle设置
6. android:windowFullscreen :是否去掉状态栏,标题栏与显示区域都属于content区域。
7. android:windowBackground :设置布局文件显示区域与标题栏显示区域的背景。
8. android:windowActionBar :标题栏部位是否使用actionbar,false则为3.0之前的标题方式。
9.让ActionBar浮在布局显示的上面,腾出空间(在setContentView之前调用)
requestWindowFeature(Window.FEATURE_ACTION_BAR);
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-->
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="MBACustomAppTheme" parent="android:Theme.Holo">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
<item name="android:actionBarStyle">@style/MBACustomActionBarStyle</item>
<item name="android:actionMenuTextAppearance">@style/ActionBarMenuTextStytle</item>
<item name="android:actionBarTabTextStyle">@style/MBAActionBarTabText</item>
<item name="android:actionBarTabStyle">@style/MBAActionBarTabs</item>
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<!-- 自定义ActionBar样式,例如:背景,title字体样式等 android:displayOptions:显示title,logo等选项;
android:backgroundStacked:设置ActionBar Tab 背景色-->
<style name="MBACustomActionBarStyle" parent="@android:style/Widget.Holo.ActionBar">
<item name="android:background">@drawable/zhiku_top_img</item>
<item name="android:titleTextStyle">@style/MBAActionBarTitleStyle</item>
<item name="android:backgroundStacked">#d27026</item>
<item name="android:displayOptions">showHome</item>
</style>
<!-- 设置 ActionBar title样式,例如:大小,颜色等 -->
<style name="MBAActionBarTitleStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">#535F6F</item>
<item name="android:textSize">30sp</item>
<item name="android:textStyle">italic</item>
</style>
<!-- 设置menu text样式,例如:大小,颜色等 -->
<style name="ActionBarMenuTextStytle">
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:actionMenuTextColor">#535F6F</item> <!-- 设置menu text颜色 -->
</style>
<!-- 设置ActionBar Tab的标签大小,颜色等 -->
<style name="MBAActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText">
<item name="android:textColor">#FF0000</item>
</style>
<style name="MBAActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">@drawable/actionbar_tab_indicator</item>
</style>
</resources>
总结的不够还望纠正,相互学习....谢谢