<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/setting"
android:orderInCategory="50"
android:showAsAction="always"
android:title="setting"/>
<item
android:id="@+id/action_share"
android:icon="@drawable/share"
android:orderInCategory="65"
android:showAsAction="ifRoom"
android:title="share"/>
<item
android:id="@+id/action_search"
android:icon="@drawable/search_lense"
android:orderInCategory="70"
android:showAsAction="ifRoom|collapseActionView"
android:title="search"/>
</menu>
android:showAsAction="ifRoom"ifRomm表示有空间的时候显示。
android:showAsAction="always"表示总是显示
android:showAsAction="never"表示总是不显示
android:showAsAction="ifRoom|withText"有空间的时候同时显示title标题
android:showAsAction="fRoom|collapseActionView"有空间的时候折叠title标题
package com.abc.action;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class CActionBarActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
// TODO 自动生成的方法存根
switch (item.getItemId()) {
case R.id.action_search:
Toast.makeText(this, "The search selected", Toast.LENGTH_SHORT).show();
break;
case R.id.setting:
Toast.makeText(this, "The setting selected", Toast.LENGTH_SHORT).show();
break;
case R.id.action_share:
Toast.makeText(this, "The share selected", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
getMenuInflater().inflate(R.menu.menu, menu);等价于
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu, menu);
onCreateOptionsMenu()方法用来获取menu文件夹中定义的menu.xml文件,用来显示action bar。
效果图:
从上图我们可以 看出明明有三个ActionButton,但是却只显示出两个,接下来就通过overflow来显示多个
(2)带有三个点的overflow菜单栏
只需要在onCreateOptionsMenu(Menu menu) 方法中调用getoverflowMenu这个方法即可
由于手机硬件情况的不同,在有物理Menu键的手机上,ActionBar的overflow按钮会有显示不出
来的情况,可以通过反射的方式修改ViewConfiguration类中的sHasPermanentMenuKey静态变量的
值永远为false,系统就是根据这个变量值来判断手机有没有物理Menu键
private void getOverflowMenu() {
//此方法是高手破解后强制overflow显示的一段代码
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
这是在真机上的效果图
这是在虚拟机上
解决办法还是有有的
按一下自带的menu键,隐藏的action button 就会从下面弹出
1、获取ActionBar对象
2、设置action bar 的 navigation mode
3、添加 action bar的 tabs
4、为每个tabs设置监听事件
5、将Tab加入ActionBar中
import java.lang.reflect.Field;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Toast;
public class CActionBarActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* getActionBar().setBackgroundDrawable(this.getBaseContext().getResources().getDrawable(R.drawable.BackBar));
getActionBar().show();*/
//1、 ActionBar
ActionBar actionbar = getActionBar();
//2、 设置action bar 的 navigation mode
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//3、 添加 action bar的 tabs Tab等价于ActionBar.Tab
Tab SnowTab = actionbar.newTab().setText("Snow_Fragment").setIcon(R.drawable.snow_org);
Tab SunTab = actionbar.newTab().setText("Sun_Fragment").setIcon(R.drawable.sunny_org);
//图片与文字可根据需要进行判断是否添加
// 将Activity的头部标题(图片的右侧)去掉/添加
actionbar.setDisplayShowTitleEnabled(true);
//给左上角图标的左边加上一个返回的图标
actionbar.setDisplayHomeAsUpEnabled(true);
//使左上角返回的图标见可点击,并进行显示与否操作
actionbar.setDisplayShowHomeEnabled(true);
/*(1)
* MyTabsListener SunTab = new MyTabsListener(new SunFragment());
SnowTab.setTabListener(SunTab);
MyTabsListener SnowTab = new MyTabsListener(new SnowFragment());
SunTab.setTabListener(SnowTab);
(2)
// 实例化 fragment action bar 是用 fragment 来显示的
Fragment sunFragment = new SunFragment();
Fragment snowFragment = new SnowFragment();
SnowTab.setTabListener(new MyTabsListener(sunFragment));
SunTab.setTabListener(new MyTabsListener(snowFragment));*/
// 4、为每个tabs设置监听事件
//(3)
SunTab.setTabListener(new MyTabsListener(new SunFragment()));
SnowTab.setTabListener(new MyTabsListener(new SnowFragment()));
//5、 将Tab加入ActionBar中
actionbar.addTab(SnowTab);
actionbar.addTab(SunTab);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
getOverflowMenu();
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_search:
Toast.makeText(this, "The search selected", Toast.LENGTH_SHORT).show();
break;
case R.id.setting:
Toast.makeText(this, "The setting selected", Toast.LENGTH_SHORT).show();
break;
case R.id.action_share:
Toast.makeText(this, "The share selected", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
private void getOverflowMenu() {
//此方法是高手破解后强制overflow显示的一段代码
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 实例化 tabs 的监听类
class MyTabsListener implements ActionBar.TabListener {
private Fragment fragment;
// 接收每个Tab对应的Fragment
//实现ActionBar.TabListener接口,构造函数中把fragment传进来了,为了更好的控制fragment
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
// 重复两次以上点击 tab
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// ft 用来控制 fragment
}
// 就点击一次
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(android.R.id.content, fragment);
}
// 不点击
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
}
SnowFragment.java
package com.abc.action;
import android.app.Fragment;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.ViewGroup;
import android.widget.FrameLayout.LayoutParams;
public class SnowFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.snow_fragment, container, false);
return view;
}
}
SunFragment.java
package com.abc.action;
import android.app.Fragment;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
public class SunFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//在Fragment中调用getActivity()方法获取Activity的实例
TextView textView = new TextView(getActivity());
//获取到Activity实例后,在Fragment中就可以通过该实例调用Activity中的方法了。另外,当Fragment需要Context对象时,也可以使用该方法
//获取Tabs中的文本
textView.setText("SUN");
//此过程可以在布局文件中完成,可参考SnowFragment.java
textView.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout layout = new LinearLayout(getActivity());
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
layout.addView(textView, params);
return layout;
}
}
snow_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="SNOW"/>
</LinearLayout>
sun_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" />
</LinearLayout>
效果图:
actionbar.newTab().setText("Snow_Fragment").setIcon(R.drawable.snow_org);
// 将Activity的头部标题(图片的右侧)去掉/添加
actionbar.setDisplayShowTitleEnabled(true);
//给左上角图标的左边加上一个返回的图标
actionbar.setDisplayHomeAsUpEnabled(true);
//使左上角返回的图标见可点击,并进行显示与否操作
actionbar.setDisplayShowHomeEnabled(true);
使返回小图标可以起到返回主菜单的功能 只需要在onOptionsItemSelected中添加相应的case即可
4、也可以将ActionBar放在手机底部,只需要在配置清单文件AndroidManifest.xml的Activity中添加android:uiOptions="splitActionBarWhenNarrow"即可public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true;
<item
android:id="@+id/action_search"
android:icon="@drawable/search_lense"
android:orderInCategory="60"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView"
android:title="search"/>
上图为折叠和展开的搜索视窗的操作栏
<resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <item name="android:actionBarStyle">@style/MyCustomActionBar</item> </style> <style name="MyCustomActionBar" parent="@android:style/Widget.Holo.ActionBar"> <item name="android:background">#00cc00</item><!-- ActionBar的背景颜色 --> <item name="android:backgroundStacked">#006600</item><!--Tabs的背景颜色 --> </style> </resources>
在AndroidManifest.xml文件中可以引用样式主题,区别:
可以在<Activity>中为一个Activity定义一个主题,也可以在中<Application>中为整个应用程序定义一个主题,如下所示:
<application android:theme="@style/CustomActionBarTheme"
或者
<activity android:theme="@style/CustomActionBarTheme"
效果图:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <item name="android:actionBarStyle">@style/MyCustomActionBar</item> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> </style> <style name="MyCustomActionBar" parent="@android:style/Widget.Holo.ActionBar"> <!-- android:theme="@style/CustomActionBarTheme" --> <item name="android:background">#00cc00</item><!-- ActionBar的背景颜色 --> <item name="android:backgroundStacked">#006600</item> <!-- Tabs的背景颜色 --> </style> <style name="MyActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText" > <!-- android:allowBackup="true" --> <item name="android:textColor">#ff9900</item><!-- Tabs的字体颜色 --> </style> </resources>
当自定义Tabs字体的时候可在清单文件中的application中添上这样一句代码
是否允许备份用户基础数据
android:allowBackup="true"
(5)自定义Tab Indicator
为了可以明确分辨出我们当前选中的是哪一个Tab项,通常情况下都会在选中Tab的下面加上一条横线作为标识,这被称作Tab Indicator。那么上图中的Tab Indicator就是蓝色的,那么我们接下来就学习一下如何自定义Tab Indicator。首先我们需要重写actionBarTabStyle这个属性,然后将它指向一个新建的Tab样式,然后重写background这个属性即可。需要注意的是,background必须要指定一个state-list drawable文件,这样在各种不同状态下才能显示出不同的效果
由(4)(5)的Tabs可以观察出我做的这两个截图的颜色相比(5)的颜色稍浅一点(为了便于理解Tab Indicator),这是因为在自定义Tab Indicator的时候每个按钮都是有两张图片组成的,也就是说我在这用了4张图片,只需要在style.xml中加入自己的图片
actionbar_tab_indicatorxml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > 引入四张已存在图片 <item android:drawable="@drawable/tab_unselected" android:state_pressed="false" android:state_selected="false"/> <item android:drawable="@drawable/tab_selected" android:state_pressed="false" android:state_selected="true"/> <item android:drawable="@drawable/tab_unselected_pressed" android:state_pressed="true" android:state_selected="false"/> <item android:drawable="@drawable/tab_selected_pressed" android:state_pressed="true" android:state_selected="true"/> </selector>
style.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <!-- 这是item的背景修改,不按时透明,按时显示绿色 --> <!-- 4 --> <item name="android:selectableItemBackground">@drawable/up_background</item> <!-- 1 --> <item name="android:actionBarStyle">@style/MyCustomActionBar</item> <!-- 2 --> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> <!-- 3 --> <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item> </style> <!-- 1 --> <style name="MyCustomActionBar" parent="@android:style/Widget.Holo.ActionBar"> <!-- android:theme="@style/CustomActionBarTheme" --> <item name="android:background">#00cc00</item><!-- ActionBar的背景颜色 --> <item name="android:backgroundStacked">#006600</item><!-- Tabs的背景颜色 --> </style> <!--2 --> <style name="MyActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText" > <!-- android:allowBackup="true" --> <item name="android:textColor">#ff9900</item><!-- Tabs的字体颜色 --> </style> <!-- 3 --> <style name="MyActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView"> <!--自定义图片 --> <item name="android:background">@drawable/actionbar_tab_indicator</item> </style> </resources>
对比注释<!-- 1 --><!-- 2 --><!-- 3 -->
在注释
<!-- 4 --> 中引用自定义的图片 <item name="android:selectableItemBackground">@drawable/up_background</item>
下面是自定义的两张图片编码和效果图:
up_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:drawable="@drawable/press_background" android:state_pressed="true"/>
<item android:drawable="@android:color/transparent"/>
</selector>
press_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#ff0000" />
<!--红色 -->
</shape>
<resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <item name="android:actionBarStyle">@style/MyCustomActionBar</item> </style> <style name="MyCustomActionBar" parent="@android:style/Widget.Holo.ActionBar"> <item name="android:background">#00cc00</item><!-- ActionBar的背景颜色 --> <item name="android:backgroundStacked">#006600</item><!--Tabs的背景颜色 --> </style> </resources>
在AndroidManifest.xml文件中可以引用样式主题,区别:
可以在<Activity>中为一个Activity定义一个主题,也可以在中<Application>中为整个应用程序定义一个主题,如下所示:
<application android:theme="@style/CustomActionBarTheme"
或者
<activity android:theme="@style/CustomActionBarTheme"
效果图:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <item name="android:actionBarStyle">@style/MyCustomActionBar</item> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> </style> <style name="MyCustomActionBar" parent="@android:style/Widget.Holo.ActionBar"> <!-- android:theme="@style/CustomActionBarTheme" --> <item name="android:background">#00cc00</item><!-- ActionBar的背景颜色 --> <item name="android:backgroundStacked">#006600</item> <!-- Tabs的背景颜色 --> </style> <style name="MyActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText" > <!-- android:allowBackup="true" --> <item name="android:textColor">#ff9900</item><!-- Tabs的字体颜色 --> </style> </resources>
当自定义Tabs字体的时候可在清单文件中的application中添上这样一句代码
是否允许备份用户基础数据
android:allowBackup="true"
(5)自定义Tab Indicator
为了可以明确分辨出我们当前选中的是哪一个Tab项,通常情况下都会在选中Tab的下面加上一条横线作为标识,这被称作Tab Indicator。那么上图中的Tab Indicator就是蓝色的,那么我们接下来就学习一下如何自定义Tab Indicator。首先我们需要重写actionBarTabStyle这个属性,然后将它指向一个新建的Tab样式,然后重写background这个属性即可。需要注意的是,background必须要指定一个state-list drawable文件,这样在各种不同状态下才能显示出不同的效果
由(4)(5)的Tabs可以观察出我做的这两个截图的颜色相比(5)的颜色稍浅一点(为了便于理解Tab Indicator),这是因为在自定义Tab Indicator的时候每个按钮都是有两张图片组成的,也就是说我在这用了4张图片,只需要在style.xml中加入自己的图片
actionbar_tab_indicatorxml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > 引入四张已存在图片 <item android:drawable="@drawable/tab_unselected" android:state_pressed="false" android:state_selected="false"/> <item android:drawable="@drawable/tab_selected" android:state_pressed="false" android:state_selected="true"/> <item android:drawable="@drawable/tab_unselected_pressed" android:state_pressed="true" android:state_selected="false"/> <item android:drawable="@drawable/tab_selected_pressed" android:state_pressed="true" android:state_selected="true"/> </selector>
style.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <!-- 这是item的背景修改,不按时透明,按时显示绿色 --> <!-- 4 --> <item name="android:selectableItemBackground">@drawable/up_background</item> <!-- 1 --> <item name="android:actionBarStyle">@style/MyCustomActionBar</item> <!-- 2 --> <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item> <!-- 3 --> <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item> </style> <!-- 1 --> <style name="MyCustomActionBar" parent="@android:style/Widget.Holo.ActionBar"> <!-- android:theme="@style/CustomActionBarTheme" --> <item name="android:background">#00cc00</item><!-- ActionBar的背景颜色 --> <item name="android:backgroundStacked">#006600</item><!-- Tabs的背景颜色 --> </style> <!--2 --> <style name="MyActionBarTabText" parent="@android:style/Widget.Holo.ActionBar.TabText" > <!-- android:allowBackup="true" --> <item name="android:textColor">#ff9900</item><!-- Tabs的字体颜色 --> </style> <!-- 3 --> <style name="MyActionBarTabs" parent="@android:style/Widget.Holo.ActionBar.TabView"> <!--自定义图片 --> <item name="android:background">@drawable/actionbar_tab_indicator</item> </style> </resources>
对比注释<!-- 1 --><!-- 2 --><!-- 3 -->
在注释
<!-- 4 --> 中引用自定义的图片 <item name="android:selectableItemBackground">@drawable/up_background</item>
下面是自定义的两张图片编码和效果图:
up_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:drawable="@drawable/press_background" android:state_pressed="true"/>
<item android:drawable="@android:color/transparent"/>
</selector>
press_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="#ff0000" />
<!--红色 -->
</shape>
下篇文章我将会继续介绍未完成的ActionBar (二)
项目资源下载

本文详细介绍了Android Action Bar的使用方法,包括如何添加简单ActionBar、带有三个点的overflow菜单栏、导航标签(navigation tabs)+ Fragment、共享事件(share action provider)、上下文操作栏(contextual action bar)、实现下拉导航与进度条刷新、显示在底部的Action Bar等,并展示了如何自定义Action Bar的外观,如主题、背景颜色、文字大小和Tab Indicator。
4万+

被折叠的 条评论
为什么被折叠?



