参考:
http://www.apkbus.com/android-125933-1-1.html
前提:
如果系统是3.0以上,就不需要进行任何操作,否则:
1, 导入工程sdk\extras\android\support\v7\appcompat(sdk中自带的)。并将该工程做为library引入到自己的项目中(该工程中自带有v7包,所以不需要自己重新导入)。
2,Activity要继承ActionbarActivity。
3 , 清单文件中的theme必须是android:theme="@style/Theme.AppCompat"或者是AppCompat的子类。
4,通过getSupportActionBar()得到Actionbar对象。
在XML中定义actions
同菜单一样,所有的action button与action overflow都可以定义在res/menu文件夹下的xml文件中,都需要通过onCreateOptionsMenu()来生成相应的界面,并通过onOptionsItemSelected()响应点击事件。
系统3.0以上
建立main.xml文件
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:showAsAction="ifRoom"
android:title="@string/action_search"/>
<item
android:id="@+id/action_settings"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>
使用v7包建立xml
大部分和3.0以上一样,只不过showAsAction
属性并不能使用android:前缀了(也就是说不能使用http://schemas.android.com/apk/res/android这个名称空间),因此我们需要自己定义xml名称空间(该名称空间的值必须是http://schemas.android.com/apk/res-auto,但是它的名可以随便取),并且使用该名称空间作为该属性的前缀。如:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myns="http://schemas.android.com/apk/res-auto" >
<!-- 自定义名称空间,值必须是http://schemas.android.com/apk/res-auto,名可以随便取 -->
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
myns:showAsAction="ifRoom"/>
<!-- showAsAction属性使用自定义的名称空间做为前缀,而不是3.0以上的android: -->
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
myns:showAsAction="never"/>
</menu>
生成界面:
重写activity中的onCreateOptionsMenu方法:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
经过以上两步,就可以在action button显示出来。
响应点击事件:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {// 得到对应的id
case R.id.action_search:
Toast.makeText(this, R.string.action_search, Toast.LENGTH_SHORT)
.show();
break;
case R.id.action_settings:
Toast.makeText(this, R.string.action_settings, Toast.LENGTH_SHORT)
.show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
返回parentActivity界面
该功能主要用于在任何非主界面的activity中都能一次性返回到parentActivity中。这是和返回键的区别:返回键只能返回到上一次界面;而该功能却返回到parentActivity,无论是parentActivity与当前activity中间隔了几个activity。
清单文件中配置parentActivity
<activity
android:name="com.baigle.demo.MainActivity"
android:logo="@drawable/small" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.baigle.demo.ThirdActivity"
android:parentActivityName="com.baigle.demo.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.baigle.demo.MainActivity" />
</activity>
注意:对ThirdActivity来说,它不但要配置parentActivityName属性,还需要加上<meta-date>标签.并且,标签中的android:name的值是固定的,android:value的值就是它的parentActivity的全名(包名+类名)。
在activity设置
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//使用v7包时调用getSupportActionbar()
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
/*
* 不使用v7包时,直接用:
* getActionBar().setDisplayHomeAsUpEnabled(true);
*/
}
//使用v7包时,该方法可以不重写
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home://此处的id值是固定的
//此处是返回到parentActivity界面中,也可以进行别的操作。
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
注意
actionbar的重叠模式(overlay mode)
v7下
<style name="CustomActionBarTheme"
parent="@android:style/Theme.AppCompat">
<item name="android:windowActionBarOverlay" tools:ignore="NewApi">true</item>
<!-- Support library compatibility -->
<item name="windowActionBarOverlay">true</item>
</style>
系统3.0
<!-- the theme applied to the application or activity 。这里复制于官方文档,按照上面的自定义style方法试了下,可以用-->
<style name="CustomActionBarTheme"
parent="@android:style/Theme.Holo">
<item name="android:windowActionBarOverlay">true</item>
</style>
问题
android:paddingTop="?android:attr/actionBarSize"
android:paddingTop="?attr/actionBarSize"
menu:
它的根结点是<menu>也就是一个菜单,可以包含<item>和<group>两个子结点。
<item>是用来定义一个菜单项的。每一个<item>下还可以包含<menu>,该<menu>就是子菜单,也就是点击该<item>后出现的菜单。
<group>是将多个<item>合成一个菜单组,<group>中的属性是对整组菜单项都是有用的。如:
<group
android:checkableBehavior="single"
test:showAsAction="always" >
<item
android:id="@+id/action4_item1"
android:title="子菜单一"/>
<item
android:id="@+id/action4_item2"
android:title="子菜单二"/>
</group>
其中的子菜单一和子菜单二属于一个菜单组,并且菜单组指定了单选。因此,这两个<item>就会以单选的形式存在,一次只能选择一个。但是它并不会和别的不包含在该<group>中的<item>冲突。
<item>节点下只能包含<menu>节点,<group>节点下也只能包含<item>节点。<group>节点是不会出现在actionbar上的,它还是需要通过菜单按键来弹出。
示例:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:test="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/action1"
android:orderInCategory="100"
android:title="菜单一"
test:showAsAction="always">
<menu>
<item
android:id="@+id/action1_item1"
android:title="子菜单一">
<menu>
<item
android:id="@+id/action1_item1_item1"
android:title="子子菜单一"/>
<item
android:id="@+id/action1_item1_item2"
android:title="子子菜单二"/>
</menu>
</item>
<item
android:id="@+id/action1_item2"
android:title="子菜单二"/>
</menu>
</item>
<group
android:checkableBehavior="single"
test:showAsAction="always" >
<item
android:id="@+id/action4_item1"
android:title="子菜单一"/>
<item
android:id="@+id/action4_item2"
android:title="子菜单二"/>
</group>
</menu>
显示普通的UI组件:
ActionBar中除了显示文字外,还可以指定一些UI组件。方法有二:
方法一:
在<item>中使用actionViewClass属性,指定一个固定的View。
方法二:
在<item>中使用actionLayout属性,指定视图对应的布局。因此,可以为该功能选项指定背景、文字颜色等选择器。
示例:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:test="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/action1_item1_item1"
test:actionViewClass="android.support.v7.widget.SearchView"
test:showAsAction="always"/>
<item
android:id="@+id/action1_item1_item2"
test:actionLayout="@layout/image_item"
android:title="子子菜单二"
test:showAsAction="always"/>
</menu>
也
要注意:
actionViewClass与actionLayout前面的也必须是自己命名的名称空间,而不能用android:。比如上面用的是test。如果是在3.0以上的系统中,可以直接用android:。
Actionbar与Fragment:
使用Actionbar的时候,继承的是ActionbarActivity,而ActionbarActivity又继承于v4包中的FragmentActivity。所以,这也给Actionbar与Fragment结合留下了可能。
示例:
public class MainActivity extends ActionBarActivity implements TabListener {
private ActionBar bar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);//设置导航样式
//设置导航条目
bar.addTab(bar.newTab().setText("第一页").setTabListener(this));
bar.addTab(bar.newTab().setText("第二页").setTabListener(this));
bar.addTab(bar.newTab().setText("第三页").setTabListener(this));
}
@Override
public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
MyFragment m = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString(MyFragment.KEY, (String) arg0.getText());
m.setArguments(bundle);//为fragment传递参数
arg1.replace(R.id.container, m);
//此处不要调用commit()方法,否则会报错。
}
@Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
}
@Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
}
}
上面的代码实现了tab标签导航。
常见问题:
一:actionbar隐藏标题。当使用actionbar实现tab标签时,标题并没有隐藏。隐藏标题:
bar.setDisplayShowHomeEnabled(false);
bar.setDisplayShowTitleEnabled(false);
二、actionbar显示在底部。有些时候actionbar会显示在底部。只需要在清单文件中进行配置:
<activity
android:name="com.baigle.demo.MainActivity"
android:label="@string/app_name"
android:theme="@style/CustomActionBarTheme"
android:uiOptions="splitActionBarWhenNarrow" >
<meta-data
android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
就是要配置uiOptions属性,并且添加<meta-data>子标签。
三、action button显示图片与文字:在<item>下设置icon,title属性,并将showAsAction加上withText值(如果多个值就用竖线隔开)。当屏幕宽度足够时,便会显示文字与图标,当宽度不够是只显示图标。如:
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:showAsAction="always|withText"
android:title="搜索"/>
四
、修改action button的点击效果(背景颜色的切换):更改style.xml中的android:actionButtonStyle属性的值,并且在该样式中更改android:background的值(点击成背景选择器就行)。如:
<style name="MyActionbar" parent="@android:style/Theme.Holo.Light">
<item name="android:actionButtonStyle">@style/buttonStyle</item>
</style>
<style name="buttonStyle" parent="Widget.ActionButton">
<item name="android:background">@drawable/action_button_bc_selector</item>
</style>
五、动态修改action view的title属性:有可能在应用中随时要修改actionview的title属性。可以在需要修改的地方调用Activity.invalidateOptionsMenu(),重写onPrepareOptionsMenu(),并在该方法中修改title属性。如下:
tv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
title += "-title";
invalidateOptionsMenu();//点击时修改title属性,会重调onPrepareOptionsMenu()
}
});
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem item = menu.findItem(R.id.tv_change);
item.setTitle(title);
return true;
}