ActionBar位于Activity的顶部,可用来显示activity的标题、Icon、Actions和一些用于交互的View。它也可被用于应用的导航。
ActionBar 是在Android 3.0(API 11)中加入到SK中的,想在低版本中使用ActionBar给项目导入Support Library v7包即可。
使用ActionBar
开发API11以下的程序,首先必须在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类,否则将无法使用ActionBar。
如:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light"
android:name=".BaseApplication"
>
2.1 创建Actions
Actions即ActionBar中的每个交互项,通常在XML文件中指定(位于res/menu)。在menu资源文件中定义Action的方法如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wangxiapp="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item android:id="@+id/action_search"
android:icon="@mipmap/ic_action_search" //搜索图标的图片
android:title="research"
android:orderInCategory="100" //此item在ActionBar的位置。当有多个item时越大越在后面
wangxiapp:showAsAction="ifRoom"
/>
</menu>
showAsAction属性用来定义每个Action是如何显示的,always表示永远显示在ActionBar中,如果屏幕空间不够则无法显示,ifRoom表示屏幕空间够的情况下显示在ActionBar中.
在Activity中创建ctionBar的Action代码位于onCreateOptionsMenu()中,下面一段代码展示了创建过程:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mainmenu, menu); //第一个参数设置ActionBar最左边的图片
return true;
}
有的时候由于一些特殊原因,最左边的图片,即应用的图标不显示,此时需要一些设置。在MainActivity中添加如下代码:
actionBar = getSupportActionBar();
actionBar.setLogo(R.mipmap.ic_launcher);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
运行效果如图:
现在我们看到了设置的图片,但没有看的我们在item中设置的title。原因是:
如果你的menu既提供了title又提供了icon属性,那么默认显示icon,如果你想要显示文字title,就添加”withText”属性,如下:
1 <item yourapp:showAsAction="ifRoom|withText" ... />
备注:“withText”属性是给action bar的一个暗示,告诉它应该显示文字title,如果可以的话,就显示,但是当icon是可用的并且action bar的空间受到限制的时候,就不一定会显示了。
你应该为每一个item声明title属性,即使你不声明title要显示,因为:
1)如果没有足够的空间显示所有的action item,那显示在overflow中的Item就只会显示title,此时图片会变成竖着的三个点,点击时就会显示title;
2)视觉受损者会读取title;
3)如果action item只显示icon,那么当用户长按item的时候,会显示一个小的提示窗口显示action的title;
icon是可选的,但是推荐使用。
开发者可以使用”always”声明一个Item永远作为action button显示,但是开发者不应该用它迫使item用这种方式显示,在空间狭小的设备上,这会引起布局问题。最好的是使用”ifRoom”。这使得系统可以根据空间做出调整。只有当Item非常重要,关系到关键特征的时候,才可以使用”always”。
当点击右边搜索图片时设置监听:代码如下:
//布局做如下修改
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wangxiapp="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item android:id="@+id/action_search"
android:icon="@mipmap/ic_action_search"
android:title="@string/action_settings"
android:orderInCategory="100"
wangxiapp:showAsAction="ifRoom"
wangxiapp:actionViewClass="android.support.v7.widget.SearchView"
/>
</menu>
//Activty如下操作
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
//获取SearchView
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
//设置搜索的监听
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
//当搜索提交的时候
@Override
public boolean onQueryTextSubmit(String query) {
ToastUtil.showToast(UiUtil.getContext(), query);
return true;
}
//当搜索文本改变的时候
@Override
public boolean onQueryTextChange(String newText) {
ToastUtil.showToast(UiUtil.getContext(), newText);
return true;
}
});
return true;
}
如果一个Action被单击,对于activity中的onOptionsItemSelected()将被调用。该函数的传入参数是一个MenuItem。通过判断该MenuItem的Id,即可确认是哪个Action被单击。现在我们通过这个事件来处理通过点击ActionBar的箭头来返回上一个Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
actionBar.setLogo(R.mipmap.ic_launcher);
//显示返回主界面的箭头
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
//ActionBar的点击监听
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//ActionBar的唯一id android.R.id.home
if (item.getItemId()==android.R.id.home){
finish();
}
return true;
}
这样就可以在其他Activity中通过点击ActionBar来完成返回上个Activity。其实onOptionsItemSelected()这个可以在其他Activity中省略的。在清单文件中为该Activity设置(即可以完成点击Activty返回上个界面):
<activity android:name=".DetailActivity"
android:parentActivityName=".MainActivity"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"
/>
</activity>
3 .实现ActionBar Tab标签
1 在Drawable 目录下 写了一个标签的状态选择器
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- STATES WHEN BUTTON IS NOT PRESSED -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false"
android:state_pressed="false"
android:drawable="@mipmap/tab_unselected" />
<item android:state_focused="false" android:state_selected="true"
android:state_pressed="false"
android:drawable="@mipmap/tab_selected" />
<!-- Focused states (such as when focused with a d-pad or mouse hover) -->
<item android:state_focused="true" android:state_selected="false"
android:state_pressed="false"
android:drawable="@mipmap/tab_unselected_focused" />
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="false"
android:drawable="@mipmap/tab_selected_focused" />
<!-- STATES WHEN BUTTON IS PRESSED -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false"
android:state_pressed="true"
android:drawable="@mipmap/tab_unselected_pressed" />
<item android:state_focused="false" android:state_selected="true"
android:state_pressed="true"
android:drawable="@mipmap/tab_selected_pressed" />
<!-- Focused states (such as when focused with a d-pad or mouse hover) -->
<item android:state_focused="true" android:state_selected="false"
android:state_pressed="true"
android:drawable="@mipmap/tab_unselected_pressed" />
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="true"
android:drawable="@mipmap/tab_selected_pressed" />
</selector>
2 实现自定义主题 (在values下创建resources)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="@style/Theme.AppCompat.Light">
<item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
<!-- Support library compatibility -->
<item name="actionBarTabStyle">@style/MyActionBarTabs</item>
</style>
<!-- ActionBar tabs styles -->
<style name="MyActionBarTabs"
parent="@style/Widget.AppCompat.ActionBar.TabView">
<!-- tab indicator -->
<item name="android:background">@drawable/actionbar_tab_indicator</item>
<!-- Support library compatibility -->
<item name="background">@drawable/actionbar_tab_indicator</item>
</style>
</resources>
3.在Activity中设置:
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = actionBar.newTab().setText("标签一").setTabListener(new MyTabListener());
actionBar.addTab(tab1);
ActionBar.Tab tab2 = actionBar.newTab().setText("标签二").setTabListener(new MyTabListener());
actionBar.addTab(tab2);
ActionBar.Tab tab3 = actionBar.newTab().setText("标签三").setTabListener(new MyTabListener());
actionBar.addTab(tab3);
ActionBar.Tab tab4 = actionBar.newTab().setText("标签四").setTabListener(new MyTabListener());
actionBar.addTab(tab4);
DrawerLayout (抽屉效果):
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/dl">
<LinearLayout
//这里的LinearLayout是一开始是看见的主布局
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
<FrameLayout
//这个布局就是抽屉,即通过测拉才可以显示的布局
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_tab"
//抽屉在左边
android:layout_gravity="left">
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
给抽屉设置监听:
ActionBarDrawerToggle :
控制抽屉的开关, 显示在actionBar 上面 (即通过点击就可以打开和关闭抽屉):
ActionBar actionBar = getSupportActionBar();
//设置显示ActionBar的点击图标没,如下图的最左边的图标
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
actionBarDrawerToggle = new ActionBarDrawerToggle(MainActivity.this, drawerLayout, R.string.app_name, R.string.app_name){
// 创建时就可以设置抽屉的监听。关闭监听
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
ToastUtil.showToast(MainActivity.this,"close");
}
//开启监听
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
ToastUtil.showToast(MainActivity.this, "open");
}
};
// 让开关和Actionbar建立关系
actionBarDrawerToggle.syncState();
//设置监听
drawerLayout.setDrawerListener(actionBarDrawerToggle);
/** 处理actionBar菜单条目的点击事件 */
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_search) {
Toast.makeText(getApplicationContext(), "搜索", 0).show();
}
//返回值很重要
return drawerToggle.onOptionsItemSelected(item)|super.onOptionsItemSelected(item);
}