一,ActionBar简介:
ActionBar是Android系统window的导航栏,从Android3.1(API-11)开始加入到Android系统中。通俗的说,ActionBar让用户在进入指定界面以后,通过ActionBar的描述可以知道在指定界面能做哪些操作。ActionBar提供了几个关键功能:
1)提供一个专门的空间,给你的app增加一个特性,并且指示用户在App中的当前位置。
2)使一些重要的操作项更加直观。
3)支持在App内导航和视图的切换。
需要注意的是:
-如果你的App支持Android API 低于 API-level-11:
import android.support.v7.app.ActionBar
-如果你的App仅支持API-11或者更 高版本:
import android.app.ActionBar
二、如何增加和移除ActionBar
由于
ActionBar从Android3.1(API-11)才开始加入,所以在创建app时,最好使用
appcompat v7
。当然,如果你的app不考虑低于API-11的版本,可以不用appcompat V7。如何让一个界面拥有有ActionBar:
1)在创建activity时,继承ActionBarActivity.
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
2)让你的activity的theme使用appcompatv7中的theme:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
如果要移除
ActionBar,可以在activity的onCreate()函数中加入以下代码:
ActionBar
actionBar
=
getSupportActionBar()
;
actionBar
.
hide
();
或许,还可以这么做,只修改theme style:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
不管使用appcompatv7与否,增加和移除ActionBar的思路都可以使用上面的两个情况,只不过调用的接口和使用的theme style不一样。或许会这么做:
ActionBar
actionBar
=
getActionBar()
;
actionBar
.
hide
();
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<item name="windowActionBar">false</item>
</style>
三、增加action Items
要增加action items,需要在xml文件中配置(res/menu/main.xml),比如新增一个搜索action:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.androidtest.MainActivity" >
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_search_category_default"
android:title="搜索"
app:showAsAction="always"/>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never"/>
</menu>
注:
app:showAsAction="always" 并不是android:showAsAction="always"(不是绝对的,主要看你的menu xml的结构),showAsAction、actionViewClass这类属性的空间命名是自定义的,请注意上面代码中的:xmlns:app="http://schemas.android.com/apk/res-auto".
然后在你的activity中重写onCreateOptionsMenu()和onOptionsItemSelected():
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
此时,点击搜索action并不会执行任何操作,因为还没有对它的响应做处理:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
case R.id.action_settings:
default:
return super.onOptionsItemSelected(item);
}
}
public void openSearch(){
Toast.makeText(getApplicationContext(), "open search!", Toast.LENGTH_LONG).show();
}
action item的
app:showAsAction属性说明:这个属性用来控制action显示还是被折叠的,它有一下几个值:
-never:表示从不显示,被折叠。
-ifRoom:表示ActionBar上有空余空间的时候就显示,没有足够的空间就折叠隐藏(不常用的action一般都设置此属性)。
-always:表示一直显示在
ActionBar空间上,不会被折叠隐藏。
-withText:表示还包括标题文本(由android:title定义),这个属性可以通过“|”配合其他属性使用:ifRoom|withText.
-collapseActionView:表示与此action item相关的action view(如android:actionLayout or android:actionViewClass)可以被合并成一个Action按钮。
四、通过ActionBar上应用程序的图标导航
要使ActionBar上应用程序的图标成为导航button,需要调用setDisplayHomeAsUpEnabled(),eg:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
效果如上图,在ActionBar左边已经多了一个箭头图标。但此时点击此图标并没有事件响应,因为没有增加对它响应时间处理,这个图标对应ID是R.id.home:
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
case R.id.action_settings:
case R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
调用
finish()以后,就相当于关闭当前应用了,然后在实际体验中,ActionBar导航button通常是返回上一级界面,这个的实现要做下面处理。
1)在清单文件中为显示的activity配置parent activity,并在MainActivity增加一个button,让其可以跳转到另一个activity(DisPlayMsgActivity)。
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- A child of the main activity -->
<!-- android:parentActivityName 要求Android 4.1以上版本 -->
<activity
android:name=".DisPlayMsgActivity"
android:label="@string/activity_show_msg"
android:parentActivityName=".MainActivity"
>
<!-- Parent activity meta-data to support API level 7+
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/> -->
</activity>
</application>
2)在
DisPlayMsgActivity.java中实现响应事件。
public class DisPlayMsgActivity extends ActionBarActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.display_msg);
//显示ActionBar up button
ActionBar mActionBar = getSupportActionBar();
mActionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//ActionBar 导航button 响应事件
case R.id.home:
Intent mIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, mIntent)) {
TaskStackBuilder.create(this)
.addNextIntentWithParentStack(mIntent)
.startActivities();
} else {
mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(this, mIntent);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
当然你也可以在
DisPlayMsgActivity.java中重写getSupportParentActivityIntent()和onCreateSupportNavigateUpTaskStack()来实现。
五、增加action View:
action 增加一个view会是一个什么样的效果呢,以搜索action 为例,先看下对比图:
看上图可知,增加action view以后,点击搜索图标,在搜素图标旁边会出来一个类似输入框的view,这个其实就上面提到过的
collapseActionView:
1)首先配置Menu xml文件:
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_search_category_default"
android:title="搜索"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>"
2)在onCreateOptionsMenu()配置searchview的属性:
...
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
//如果API-level 高于 11,直接用下面方法
//menu.findItem(R.id.action_search).getActionView();
//配置searchView的属性
MenuItemCompat.setOnActionExpandListener(searchItem, new OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem arg0) {
// Do something when collapsed
return false;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem arg0) {
// Do something when expanded
return false;
}
});
...
六、增加Action Provider:
1)在menu增加分享的item:
<item
android:id="@+id/action_share"
android:title="分享"
app:showAsAction="ifRoom"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
2)在onCreateOptionsMenu()设置分享的intent:
...
// Set up ShareActionProvider's default share intent
MenuItem shareItem = menu.findItem(R.id.action_share);
mShareActionProvider = (ShareActionProvider)
MenuItemCompat.getActionProvider(shareItem);
mShareActionProvider.setShareIntent(getDefaultIntent());
return super.onCreateOptionsMenu(menu);
...
private Intent getDefaultIntent() {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
return intent;
}