这篇文章将对ActionBar专题前面几篇学习过的内容作一个总结,顺便运用之前学过的知识实现一个自定义样式的ActionBar标题栏效果。话很少说,进入今天的正题。
1、实现效果图 html
竖屏效果图:最左边是Logo图标,右边是工具栏按钮,点击Menu键显示其他的按钮键,下方是Tab标签选项。 java
横屏效果图:竖屏中的Tab选项标签变成了中间的下拉导航按钮 android
2、项目结构图 app

3、编码准备工做 框架
先来学习一下自定义样式的基础知识,以便你们能看懂关于后面的代码。 ide
一、设置操做栏的样式 工具
若是你对应用程序中的可视构件进行了定制化的设计,那么你可能也会要对操做栏作一些从新设计,以便跟应用程序的设计匹配。要这样作的话,须要使用Android的样式与主题框架中的一些特殊的样式属性来从新设置操做栏的样式。 布局
注意:改变外观的背景图片依赖与当前按钮的状态(选择、按下、解除选择),所以你使用的可描画的资源必须是一个可描画的状态列表。 post
警告:对于你提供的全部可描画的背景,要确保使用NinePatch类型可描画资源,以便容许图片的拉伸。NinePatch类型的图片应该比40像素高30像素宽的图片要小。 学习
二、普通的外观
android:windowActionBarOverlay
这个属性声明了操做栏是否应该覆盖Activity布局,而不是相对Activity的布局位置的偏移。这个属性的默认值是false。
一般,在屏幕上,操做栏须要它本身的空间,而且把剩下的空间用来填充Activity的布局。当操做栏四覆盖模式时,Activity会使用全部的有效空 间,系统会在Activity的上面描画操做栏。若是你想要在操做栏隐藏和显示时,布局中的内容保持固定的尺寸好位置,那么这种覆盖模式是有用的。你也可 能只是为了显示效果来使用它,由于你能够给操做栏设置半透明的背景,以便用户依然可以看到操做栏背后的Activity布局。
注意:默认状况下,Holo主题会用半透明背景来描画操做栏。可是,你可以用本身的样式来修改它,而且默认的状况下,DeviceDefault主题在不一样的设备上可能使用不透明的背景。
覆盖模式被启用时,Activity布局不会感知到操做栏覆盖在它的上面,所以,在操做栏覆盖的区域,最好不要放置一些重要的信息或UI组件。若是适 合,你可以引用平台的actionBarSize值来决定操做栏的高度,例如,在XML布局文件中引用这个值。
- <SomeView
- ...
- android:layout_marginTop="?android:attr/actionBarSize" />
你还可以用getHeight()方法在运行时获取操做栏的高度。若是在Activity生存周期的早期调用这个方法,那么在调用时所反映的操做栏的高度可能不包括被堆放的操做栏(由于导航选项标签)。要看如何在运行时判断操做栏总的高度(包括被堆放的操做栏),请看Honeycomb Gallery示例应用中的TitlesFragment类。
三、操做项元素
android:actionButtonStyle
给操做项按钮定义样式资源。
android:actionBarItemBackground
给每一个操做项的背景定义可描画资源(被添加在API 级别 14中)。
android:itemBackground
给每一个悬浮菜单项的背景定义可描画资源。
android:actionBarDivider
给操做项之间的分隔线定义可描画资源(被添加在API 级别 14中)
android:actionMenuTextColor
给显示在操做项中文本定义颜色。
android:actionMenuTextAppearance
给显示在操做项中文本定义样式资源。
android:actionBarWidgetTheme
给做为操做视窗被填充到操做栏中的可视构件定义主题资源(被添加在API级别14中)。
四、导航选项标签
android:actionBarTabStyle
给操做栏中的选项标签订义样式资源。
android:actionBarTabBarStyle
给显示在导航选项标签下方的细条定义样式资源。
android:actionBarTabTextStyle
给导航选项标签中的文本定义样式资源。
五、下拉列表
android:actionDropDownStyle
给下拉导航列表定义样式(如背景和文本样式)。
如,下例XML文件中给操做栏定义了一些定制的样式:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <!-- the theme applied to the application or activity -->
- <style name="CustomActivityTheme" parent="@android :style/Theme.Holo">
- <item name="android:actionBarTabTextStyle">@style/CustomTabTextStyle</item>
- <item name="android:actionBarDivider">@drawable/ab_divider</item>
- <item name="android:actionBarItemBackground">@drawable/ab_item_background</item>
- </style>
-
- <!-- style for the action bar tab text -->
- <style name="CustomTabTextStyle" parent="@android :style/TextAppearance.Holo">
- <item name="android:textColor">#2456c2</item>
- </style>
- </resources>
注意:必定要在<style>标签中声明一个父主题,这样定制的主题能够继承全部没有明确声明的样式。在修改操做栏样式时,使用父主题是相当重要的,它会让你可以简单的覆写你想要改变的操做栏样式,而不影响你不想修改的样式(如文本的外观或操做项的边缘)。
你可以在清单文件中把定制的主题应用到整个应用程序或一个单独的Activity对象,如:
- <application android:theme="@style/CustomActivityTheme" ... />
六、高级样式
若是须要比上述属性更高级的样式,能够在Activity的主题中包含android:actionBarStyle和 android:actionBarSplitStyle属性。这两个属性的每个都指定了另外一种可以给操做栏定义各类属性的样式,包括带有 android:background、android:backgroundSplit、android:backgroundStacked属性的不 同背景。若是要覆盖这些操做栏样式,就要确保定义一个像Widget.Holo.ActionBar这样的父操做栏样式。
例如,若是要改变操做栏背景,你可使用下列样式:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <!-- the theme applied to the application or activity -->
- <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
- <item name="android:actionBarStyle">@style/MyActionBar</item>
- <!-- other activity and action bar styles here -->
- </style>
-
- <!-- style for the action bar backgrounds -->
- <style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
- <item name="android:background">@drawable/ab_background</item>
- <item name="android:backgroundStacked">@drawable/ab_background</item>
- <item name="android:backgroundSplit">@drawable/ab_split_background</item>
- </style>
- </resources>
4、详细代码编写
一、整个项目中最核心的地方就是在res/values下的styles.xml文件中,这是自定义风格样式的资源文件,styles.xml:
- <resources xmlns:android="http://schemas.android.com/apk/res/android">
-
- <style name="AppBaseTheme" parent="android:Theme"></style>
-
- <!-- 将自定义的style取名为CustomTheme,父类为Theme.Holo.Light,也就是说默认背景是白底黑字(若是是Theme.Holo,则默认是黑底白字) -->
- <style name="CustomTheme" parent="android:style/Theme.Holo.Light">
- <!-- 这是item的背景修改,不按时透明,按时显示绿色 -->
- <item name="android:selectableItemBackground">@drawable/ad_selectable_background</item>
- <item name="android:actionBarTabStyle">@style/MyActionBarTabStyle</item>
- <item name="android:actionBarTabTextStyle">@style/MyActionBarTabTextStyle</item>
- <item name="android:actionDropDownStyle">@style/MyDropDownNav</item>
- <item name="android:dropDownListViewStyle">@style/MyDropDownListView</item>
- </style>
-
- <!-- Tab选项标签的样式 -->
- <style name="MyActionBarTabStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabView">
- <item name="android:background">@drawable/actionbar_tab_bg</item>
- <item name="android:paddingLeft">22dp</item>
- <item name="android:paddingRight">22dp</item>
- </style>
-
- <!-- Tab选项标签字体的样式 -->
- <style name="MyActionBarTabTextStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabText">
- <item name="android:textColor">#ff0000</item>
- <item name="android:textSize">12sp</item>
- </style>
-
- <!-- 下拉导航外部按钮的样式 -->
- <style name="MyDropDownNav" parent="android:style/Widget.Holo.Light.Spinner">
- <item name="android:background">@drawable/ad_spinner_background_holo_light</item>
- <item name="android:popupBackground">@drawable/ad_menu_dropdown_panel_holo_light</item>
- <item name="android:dropDownSelector">@drawable/ad_selectable_background</item>
- </style>
-
- <!-- 下拉导航内部按钮的样式 -->
- <style name="MyDropDownListView" parent="android:style/Widget.Holo.ListView.DropDown">
- <item name="android:listSelector">@drawable/ad_selectable_background</item>
- </style>
-
- </resources>
二、定义好了以后,在AndroidManifest.xml清单文件中使用,能够在application中使用,这样就会做用于每个Activity,也能够在每个单独的Activity中使用,AndroidManifest.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.yangyu.myactionbar05"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="14" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:logo="@drawable/xianjian_logo"
- android:theme="@style/CustomTheme" >
-
- <activity
- android:name="com.yangyu.myactionbar05.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>
-
- </application>
-
- </manifest>
三、新建一个drawable文件夹,在文件夹下再定义几个资源文件:
<1> 用于tab选项标签背景的修改, actionbar_tab_bg.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/ad_tab_unselected_holo" />
- <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
- <item android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
- <item android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
-
- </selector>
<2> ActionBar标题栏的背景渐变色,actionbar_gradient_bg.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle" >
-
- <gradient
- android:angle="270"
- android:endColor="#FFEFEFEF"
- android:startColor="#cc1115"
- android:type="linear" />
-
- </shape>
<3> 用于下拉列表背景的变换,ad_spinner_background_holo_light.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:drawable="@drawable/spinner_disabled_holo_light" android:state_enabled="false"/>
- <item android:drawable="@drawable/ad_spinner_pressed_holo_light" android:state_pressed="true"/>
- <item android:drawable="@drawable/ad_spinner_focused_holo_light" android:state_focused="true" android:state_pressed="false"/>
- <item android:drawable="@drawable/spinner_default_holo_light"/>
-
- </selector>
<4> ActionBar标题栏上的按钮选中时的背景颜色切换,
selected_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="#FFA4C639" />
-
- </shape>
ad_selectable_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/selected_background" android:state_pressed="true"/>
- <item android:drawable="@android:color/transparent"/>
-
- </selector>
四、菜单的资源文件,main_menu.xml:
- <menu xmlns:android="http://schemas.android.com/apk/res/android" >
-
- <!-- 自定义搜索按钮视图 -->
- <item
- android:id="@+id/menu_search"
- android:actionViewClass="android.widget.SearchView"
- android:showAsAction="ifRoom"
- android:title="@string/action_label_search"/>
-
- <!-- 刷新按钮图标 -->
- <item
- android:id="@+id/menu_refresh"
- android:icon="@drawable/ic_menu_refresh_holo_light"
- android:showAsAction="ifRoom"
- android:title="@string/action_label_refresh"/>
-
- <!-- 收藏按钮图标加文字 -->
- <item
- android:id="@+id/menu_collected"
- android:icon="@drawable/ic_menu_star_holo_light"
- android:showAsAction="ifRoom|withText"
- android:title="@string/action_label_collected"/>
-
- </menu>
这里的资源文件有点多,为了节省篇幅,讲解重点和难点,博主这里就不一一列出来了,有须要的同窗能够看源码,一目了然。
五、主Activity程序入口类,MainActivity.java:
- package com.yangyu.myactionbar05;
-
- import android.app.ActionBar;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.Menu;
- import android.view.MenuItem;
-
- /**
- * @author yangyu
- * 主Activity,程序入口类
- */
- public class MainActivity extends Activity {
- //定义ActionBar
- private ActionBar actionBar;
-
- //定义Handler对象
- private final Handler handler = new Handler();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- initView();
-
- initData();
- }
-
- /**
- * 初始化组件
- */
- private void initView(){
- //获得ActionBar
- actionBar = getActionBar();
- }
-
- /**
- * 初始化数据
- */
- private void initData(){
- //设置ActionBar标题不显示
- actionBar.setDisplayShowTitleEnabled(false);
-
- //设置ActionBar的背景
- actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_gradient_bg));
-
- //设置ActionBar左边默认的图标是否可用
- actionBar.setDisplayUseLogoEnabled(true);
-
- //设置导航模式为Tab选项标签导航模式
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
- //设置ActinBar添加Tab选项标签
- actionBar.addTab(actionBar.newTab().setText("TAB1").setTabListener(new MyTabListener<FragmentPage1>(this,FragmentPage1.class)));
- actionBar.addTab(actionBar.newTab().setText("TAB2").setTabListener(new MyTabListener<FragmentPage2>(this,FragmentPage2.class)));
- actionBar.addTab(actionBar.newTab().setText("TAB3").setTabListener(new MyTabListener<FragmentPage3>(this,FragmentPage3.class)));
-
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main_menu, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(final MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_refresh:
- //选中刷新按钮后刷新一秒钟
- item.setActionView(R.layout.actionbar_progress);
- handler.postDelayed(new Runnable() {
- public void run() {
- item.setActionView(null);
- }
- }, 1000);
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- }
六、Tab选项标签监听接口类,MyTabListener.java:
- package com.yangyu.myactionbar05;
-
- import android.app.ActionBar.Tab;
- import android.app.ActionBar.TabListener;
- import android.app.Activity;
- import android.app.Fragment;
- import android.app.FragmentTransaction;
-
- /**
- * @author yangyu
- * 功能描述:Tab选项标签监听接口
- */
- public class MyTabListener<T extends Fragment> implements TabListener {
- private Fragment fragment;
-
- private final Activity mActivity;
-
- private final Class<T> mClass;
-
- public MyTabListener(Activity activity, Class<T> clz){
- mActivity = activity;
-
- mClass = clz;
- }
-
- @Override
- public void onTabSelected(Tab tab, FragmentTransaction ft) {
- if(fragment == null){
- fragment = Fragment.instantiate(mActivity, mClass.getName());
- ft.add(android.R.id.content, fragment, null);
- }
- ft.attach(fragment);
- }
-
- @Override
- public void onTabUnselected(Tab tab, FragmentTransaction ft) {
- if (fragment != null) {
- ft.detach(fragment);
- }
- }
-
- @Override
- public void onTabReselected(Tab tab, FragmentTransaction ft) {
-
- }
- }
-
七、Fragment类,用于显示Tab选项标签的内容,列出其中一个,FragmentPage1.java:
- package com.yangyu.myactionbar05;
-
- import android.app.Fragment;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
-
- public class FragmentPage1 extends Fragment{
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
-
- return inflater.inflate(R.layout.fragment_1, null);
- }
- }