转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9087941  

这篇文章将对ActionBar专题前面几篇学习过的内容做一个总结,顺便运用以前学过的知识实现一个自定义样式的ActionBar标题栏效果。话不多说,进入今天的正题。

一、实现效果图

竖屏效果图:最左边是Logo图标,右边是工具栏按钮,点击Menu键显示其余的按钮键,下方是Tab标签选项。

横屏效果图:竖屏中的Tab选项标签变成了中间的下拉导航按钮

二、项目结构图



三、编码准备工作


先来学习一下自定义样式的基础知识,以便大家能看懂关于后面的代码。

1、设置操作栏的样式

如果你对应用程序中的可视构件进行了定制化的设计,那么你可能也会要对操作栏做一些重新设计,以便跟应用程序的设计匹配。要这样做的话,需要使用Android的样式与主题框架中的一些特殊的样式属性来重新设置操作栏的样式。

注意:改变外观的背景图片依赖与当前按钮的状态(选择、按下、解除选择),因此你使用的可描画的资源必须是一个可描画的状态列表。

警告:对于你提供的所有可描画的背景,要确保使用NinePatch类型可描画资源,以便允许图片的拉伸。NinePatch类型的图片应该比40像素高30像素宽的图片要小。

2、普通的外观

android:windowActionBarOverlay

     

这个属性声明了操作栏是否应该覆盖Activity布局,而不是相对Activity的布局位置的偏移。这个属性的默认值是false。

通常,在屏幕上,操作栏需要它自己的空间,并且把剩下的空间用来填充Activity的布局。当操作栏四覆盖模式时,Activity会使用所有的有效空间,系统会在Activity的上面描画操作栏。如果你想要在操作栏隐藏和显示时,布局中的内容保持固定的尺寸好位置,那么这种覆盖模式是有用的。你也可能只是为了显示效果来使用它,因为你可以给操作栏设置半透明的背景,以便用户依然能够看到操作栏背后的Activity布局。

注意:默认情况下,Holo主题会用半透明背景来描画操作栏。但是,你能够用自己的样式来修改它,并且默认的情况下,DeviceDefault主题在不同的设备上可能使用不透明的背景。

覆盖模式被启用时,Activity布局不会感知到操作栏覆盖在它的上面,因此,在操作栏覆盖的区域,最好不要放置一些重要的信息或UI组件。如果适合,你能够引用平台的actionBarSize值来决定操作栏的高度,例如,在XML布局文件中引用这个值。

[html] view plaincopy
  1. <SomeView
  2. ...
  3. android:layout_marginTop="?android:attr/actionBarSize" />

你还能够用getHeight()方法在运行时获取操作栏的高度。如果在Activity生存周期的早期调用这个方法,那么在调用时所反映的操作栏的高度可能不包括被堆放的操作栏(因为导航选项标签)。要看如何在运行时判断操作栏总的高度(包括被堆放的操作栏),请看Honeycomb Gallery示例应用中的TitlesFragment类。

3、操作项元素

android:actionButtonStyle

给操作项按钮定义样式资源。

android:actionBarItemBackground

 给每个操作项的背景定义可描画资源(被添加在API 级别 14中)。

android:itemBackground

 给每个悬浮菜单项的背景定义可描画资源。

android:actionBarDivider

给操作项之间的分隔线定义可描画资源(被添加在API 级别 14中)

android:actionMenuTextColor

给显示在操作项中文本定义颜色。

android:actionMenuTextAppearance

 给显示在操作项中文本定义样式资源。

android:actionBarWidgetTheme

给作为操作视窗被填充到操作栏中的可视构件定义主题资源(被添加在API级别14中)。

4、导航选项标签

android:actionBarTabStyle

 给操作栏中的选项标签定义样式资源。

android:actionBarTabBarStyle

给显示在导航选项标签下方的细条定义样式资源。

android:actionBarTabTextStyle

给导航选项标签中的文本定义样式资源。

5、下拉列表

android:actionDropDownStyle

 给下拉导航列表定义样式(如背景和文本样式)。如,下例XML文件中给操作栏定义了一些定制的样式:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <!-- the theme applied to the application or activity -->
  4. <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
  5. <item name="android:actionBarTabTextStyle">@style/CustomTabTextStyle</item>
  6. <item name="android:actionBarDivider">@drawable/ab_divider</item>
  7. <item name="android:actionBarItemBackground">@drawable/ab_item_background</item>
  8. </style>
  9. <!-- style for the action bar tab text -->
  10. <style name="CustomTabTextStyle" parent="@android:style/TextAppearance.Holo">
  11. <item name="android:textColor">#2456c2</item>
  12. </style>
  13. </resources>

注意:一定要在<style>标签中声明一个父主题,这样定制的主题可以继承所有没有明确声明的样式。在修改操作栏样式时,使用父主题是至关重要的,它会让你能够简单的覆写你想要改变的操作栏样式,而不影响你不想修改的样式(如文本的外观或操作项的边缘)。

你能够在清单文件中把定制的主题应用到整个应用程序或一个单独的Activity对象,如:

[html] view plaincopy
  1. <application android:theme="@style/CustomActivityTheme" ... />

6、高级样式

如果需要比上述属性更高级的样式,可以在Activity的主题中包含android:actionBarStyle和android:actionBarSplitStyle属性。这两个属性的每一个都指定了另一种能够给操作栏定义各种属性的样式,包括带有android:background、android:backgroundSplit、android:backgroundStacked属性的不同背景。如果要覆盖这些操作栏样式,就要确保定义一个像Widget.Holo.ActionBar这样的父操作栏样式。

例如,如果要改变操作栏背景,你可以使用下列样式:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <!-- the theme applied to the application or activity -->
  4. <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
  5. <item name="android:actionBarStyle">@style/MyActionBar</item>
  6. <!-- other activity and action bar styles here -->
  7. </style>
  8. <!-- style for the action bar backgrounds -->
  9. <style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
  10. <item name="android:background">@drawable/ab_background</item>
  11. <item name="android:backgroundStacked">@drawable/ab_background</item>
  12. <item name="android:backgroundSplit">@drawable/ab_split_background</item>
  13. </style>
  14. </resources>

四、详细代码编写

1、整个项目中最核心的地方就是在res/values下的styles.xml文件中,这是自定义风格样式的资源文件,styles.xml:

[html] view plaincopy
  1. <resources xmlns:android="http://schemas.android.com/apk/res/android">
  2. <style name="AppBaseTheme" parent="android:Theme"></style>
  3. <!-- 将自定义的style取名为CustomTheme,父类为Theme.Holo.Light,也就是说默认背景是白底黑字(如果是Theme.Holo,则默认是黑底白字) -->
  4. <style name="CustomTheme" parent="android:style/Theme.Holo.Light">
  5. <!-- 这是item的背景修改,不按时透明,按时显示绿色  -->
  6. <item name="android:selectableItemBackground">@drawable/ad_selectable_background</item>
  7. <item name="android:actionBarTabStyle">@style/MyActionBarTabStyle</item>
  8. <item name="android:actionBarTabTextStyle">@style/MyActionBarTabTextStyle</item>
  9. <item name="android:actionDropDownStyle">@style/MyDropDownNav</item>
  10. <item name="android:dropDownListViewStyle">@style/MyDropDownListView</item>
  11. </style>
  12. <!-- Tab选项标签的样式 -->
  13. <style name="MyActionBarTabStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabView">
  14. <item name="android:background">@drawable/actionbar_tab_bg</item>
  15. <item name="android:paddingLeft">22dp</item>
  16. <item name="android:paddingRight">22dp</item>
  17. </style>
  18. <!-- Tab选项标签字体的样式 -->
  19. <style name="MyActionBarTabTextStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabText">
  20. <item name="android:textColor">#ff0000</item>
  21. <item name="android:textSize">12sp</item>
  22. </style>
  23. <!-- 下拉导航外部按钮的样式 -->
  24. <style name="MyDropDownNav" parent="android:style/Widget.Holo.Light.Spinner">
  25. <item name="android:background">@drawable/ad_spinner_background_holo_light</item>
  26. <item name="android:popupBackground">@drawable/ad_menu_dropdown_panel_holo_light</item>
  27. <item name="android:dropDownSelector">@drawable/ad_selectable_background</item>
  28. </style>
  29. <!-- 下拉导航内部按钮的样式 -->
  30. <style name="MyDropDownListView" parent="android:style/Widget.Holo.ListView.DropDown">
  31. <item name="android:listSelector">@drawable/ad_selectable_background</item>
  32. </style>
  33. </resources>

2、定义好了之后,在AndroidManifest.xml清单文件中使用,可以在application中使用,这样就会作用于每一个Activity,也可以在每一个单独的Activity中使用,AndroidManifest.xml:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.yangyu.myactionbar05"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6. <uses-sdk
  7. android:minSdkVersion="11"
  8. android:targetSdkVersion="14" />
  9. <application
  10. android:allowBackup="true"
  11. android:icon="@drawable/ic_launcher"
  12. android:label="@string/app_name"
  13. android:logo="@drawable/xianjian_logo"
  14. android:theme="@style/CustomTheme" >
  15. <activity
  16. android:name="com.yangyu.myactionbar05.MainActivity"
  17. android:label="@string/app_name">
  18. <intent-filter>
  19. <action android:name="android.intent.action.MAIN" />
  20. <category android:name="android.intent.category.LAUNCHER" />
  21. </intent-filter>
  22. </activity>
  23. </application>
  24. </manifest>

3、新建一个drawable文件夹,在文件夹下再定义几个资源文件:

<1> 用于tab选项标签背景的修改, actionbar_tab_bg.xml:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/ad_tab_unselected_holo" />
  4. <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
  5. <item android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
  6. <item android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
  7. </selector>

<2> ActionBar标题栏的背景渐变色,actionbar_gradient_bg.xml:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:shape="rectangle" >
  4. <gradient
  5. android:angle="270"
  6. android:endColor="#FFEFEFEF"
  7. android:startColor="#cc1115"
  8. android:type="linear" />
  9. </shape>

<3> 用于下拉列表背景的变换,ad_spinner_background_holo_light.xml:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:drawable="@drawable/spinner_disabled_holo_light" android:state_enabled="false"/>
  4. <item android:drawable="@drawable/ad_spinner_pressed_holo_light" android:state_pressed="true"/>
  5. <item android:drawable="@drawable/ad_spinner_focused_holo_light" android:state_focused="true" android:state_pressed="false"/>
  6. <item android:drawable="@drawable/spinner_default_holo_light"/>
  7. </selector>

<4> ActionBar标题栏上的按钮选中时的背景颜色切换,

selected_background.xml:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:shape="rectangle" >
  4. <solid android:color="#FFA4C639" />
  5. </shape>

ad_selectable_background.xml:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
  3. <item android:drawable="@drawable/selected_background" android:state_pressed="true"/>
  4. <item android:drawable="@android:color/transparent"/>
  5. </selector>

4、菜单的资源文件,main_menu.xml:

[html] view plaincopy
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android" >
  2. <!-- 自定义搜索按钮视图 -->
  3. <item
  4. android:id="@+id/menu_search"
  5. android:actionViewClass="android.widget.SearchView"
  6. android:showAsAction="ifRoom"
  7. android:title="@string/action_label_search"/>
  8. <!-- 刷新按钮图标 -->
  9. <item
  10. android:id="@+id/menu_refresh"
  11. android:icon="@drawable/ic_menu_refresh_holo_light"
  12. android:showAsAction="ifRoom"
  13. android:title="@string/action_label_refresh"/>
  14. <!-- 收藏按钮图标加文字 -->
  15. <item
  16. android:id="@+id/menu_collected"
  17. android:icon="@drawable/ic_menu_star_holo_light"
  18. android:showAsAction="ifRoom|withText"
  19. android:title="@string/action_label_collected"/>
  20. </menu>

这里的资源文件有点多,为了节省篇幅,讲解重点和难点,博主这里就不一一列出来了,有需要的同学可以看源码,一目了然。

5、主Activity程序入口类,MainActivity.java:

[java] view plaincopy
  1. package com.yangyu.myactionbar05;
  2. import android.app.ActionBar;
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.os.Handler;
  6. import android.view.Menu;
  7. import android.view.MenuItem;
  8. /**
  9. * @author yangyu
  10. *  主Activity,程序入口类
  11. */
  12. public class MainActivity extends Activity {
  13. //定义ActionBar
  14. private ActionBar actionBar;
  15. //定义Handler对象
  16. private final Handler handler = new Handler();
  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.activity_main);
  21. initView();
  22. initData();
  23. }
  24. /**
  25. * 初始化组件
  26. */
  27. private void initView(){
  28. //得到ActionBar
  29. actionBar = getActionBar();
  30. }
  31. /**
  32. * 初始化数据
  33. */
  34. private void initData(){
  35. //设置ActionBar标题不显示
  36. actionBar.setDisplayShowTitleEnabled(false);
  37. //设置ActionBar的背景
  38. actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_gradient_bg));
  39. //设置ActionBar左边默认的图标是否可用
  40. actionBar.setDisplayUseLogoEnabled(true);
  41. //设置导航模式为Tab选项标签导航模式
  42. actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
  43. //设置ActinBar添加Tab选项标签
  44. actionBar.addTab(actionBar.newTab().setText("TAB1").setTabListener(new MyTabListener<FragmentPage1>(this,FragmentPage1.class)));
  45. actionBar.addTab(actionBar.newTab().setText("TAB2").setTabListener(new MyTabListener<FragmentPage2>(this,FragmentPage2.class)));
  46. actionBar.addTab(actionBar.newTab().setText("TAB3").setTabListener(new MyTabListener<FragmentPage3>(this,FragmentPage3.class)));
  47. }
  48. @Override
  49. public boolean onCreateOptionsMenu(Menu menu) {
  50. getMenuInflater().inflate(R.menu.main_menu, menu);
  51. return true;
  52. }
  53. @Override
  54. public boolean onOptionsItemSelected(final MenuItem item) {
  55. switch (item.getItemId()) {
  56. case R.id.menu_refresh:
  57. //选中刷新按钮后刷新一秒钟
  58. item.setActionView(R.layout.actionbar_progress);
  59. handler.postDelayed(new Runnable() {
  60. public void run() {
  61. item.setActionView(null);
  62. }
  63. }, 1000);
  64. return true;
  65. }
  66. return super.onOptionsItemSelected(item);
  67. }
  68. }
[java] view plaincopy

6、Tab选项标签监听接口类,MyTabListener.java:

[java] view plaincopy
  1. package com.yangyu.myactionbar05;
  2. import android.app.ActionBar.Tab;
  3. import android.app.ActionBar.TabListener;
  4. import android.app.Activity;
  5. import android.app.Fragment;
  6. import android.app.FragmentTransaction;
  7. /**
  8. * @author yangyu
  9. *  功能描述:Tab选项标签监听接口
  10. */
  11. public class MyTabListener<T extends Fragment> implements TabListener {
  12. private Fragment fragment;
  13. private final Activity mActivity;
  14. private final Class<T> mClass;
  15. public MyTabListener(Activity activity, Class<T> clz){
  16. mActivity = activity;
  17. mClass = clz;
  18. }
  19. @Override
  20. public void onTabSelected(Tab tab, FragmentTransaction ft) {
  21. if(fragment == null){
  22. fragment = Fragment.instantiate(mActivity, mClass.getName());
  23. ft.add(android.R.id.content, fragment, null);
  24. }
  25. ft.attach(fragment);
  26. }
  27. @Override
  28. public void onTabUnselected(Tab tab, FragmentTransaction ft) {
  29. if (fragment != null) {
  30. ft.detach(fragment);
  31. }
  32. }
  33. @Override
  34. public void onTabReselected(Tab tab, FragmentTransaction ft) {
  35. }
  36. }
[java] view plaincopy

7、Fragment类,用于显示Tab选项标签的内容,列出其中一个,FragmentPage1.java:

[java] view plaincopy
  1. package com.yangyu.myactionbar05;
  2. import android.app.Fragment;
  3. import android.os.Bundle;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. public class FragmentPage1 extends Fragment{
  8. @Override
  9. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  10. Bundle savedInstanceState) {
  11. return inflater.inflate(R.layout.fragment_1, null);
  12. }
  13. }

关于ActionBar的内容总结到这里差不多就要结束了,今后如果有什么关于ActionBar好玩好用的东西再拿出来更大家一起分享、总结和交流。在这里博主希望大家能积极评论,指出文中的不足和错误的地方,博主一定第一时间改正和完善。谢谢支持!下一篇开始会讲解自定义的顶部标题栏,敬请期待!

源码下载地址

【Android UI设计与开发】第13期:顶部标题栏(四)自定义ActionBar风格和样式相关推荐

  1. 【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单...

    前一篇文章中有用到 PopupWindow 来实现弹窗的功能.简单介绍以下吧. 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图.出现的弹出窗口是一个浮动容器的当前活动. 1.首先来 ...

  2. 【Android UI设计与开发】9:滑动菜单栏(一)开源项目SlidingMenu的使用和示例-转...

    一.SlidingMenu简介 相信大家对SlidingMenu都不陌生了,它是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右滑出现设置界面效果,能方便的进行各种操作.很多优秀的应用都采用了 ...

  3. 【Android UI设计与开发】第02期:引导界面(二)使用ViewPager实现欢迎引导页面

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/8980917 本系列文章都会以一个程序的实例开发为主线来进行讲解,以求达到一个 ...

  4. android ui设计与开发工具,Android用户体验与UI设计

    Android用户体验与UI设计 编辑 锁定 讨论 上传视频 本词条缺少概述图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 本书是一部介绍Android用户体验.UI设计理念和方法论的作品 ...

  5. 【Android UI设计与开发】第09期:底部菜单栏(四)Fragment+PopupWindow仿QQ空间最新版底部菜单栏

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9023451          在今天的这篇文章当中,我依然会以实战加理论结合 ...

  6. 【Android UI设计与开发】第06期:底部菜单栏(一)使用TabActivity实现底部菜单栏

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/8989063       从这一篇文章开始,我们将进入到一个应用程序主界面UI ...

  7. 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/8987342  这篇文章算是对整个引导界面开发专题的一个终结了吧,个人觉得大部 ...

  8. 【Android UI设计与开发】第01期:引导界面(一)ViewPager介绍和使用详解

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/8980917 做Android开发加起来差不多也有一年多的时间了,总是想写点自 ...

  9. 【Android UI设计与开发】第11期:顶部标题栏(二)ActionBar实现Tab选项卡和下拉导航列表

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9050573  在上一篇文章中,我们只是大概的了解了一下关于ActionBar ...

最新文章

  1. 第一记: JS变量类型判断(VUE源码解读)
  2. 计算机尖端技术,不可思议的尖端技术:Top10
  3. 成功解决ValueError: Shape of passed values is (1, 332), indices imply (1, 1)
  4. Hadoop之HDFS常用Shell命令
  5. 数据库知识:SQLServer变量相关知识介绍
  6. 杭州保俶塔实验机器人_【科教有闻】高照实验学校Pepper机器人课程亮相2020(杭州)国际数字教育大会“智能教育引领未来”论坛...
  7. python实例化次数怎么算,我需要一个Python类来跟踪它被实例化的次数
  8. 问题解决: 此文件来自其他计算机,可能被阻止以帮助保护该计算机/WORD在试图打开文件时遇到错误……
  9. 一些好用的nginx第三方模块
  10. Java练习——小游戏 模拟雷电
  11. 路由器原理和路由协议介绍
  12. 生信文献学习(part1)--PRECISE: a ... approach to transfer predictors of drug response from pre-clinical ...
  13. Linux环境创建oracle数据库
  14. 小学计算机知识点总结怎么写,小学信息技术教学期末总结范文
  15. shell一键自动化批量安装服务
  16. 数据库视图view的解析
  17. 乐视还有400多位员工?过着没有老板的神仙日子 官方出来回应了...
  18. java abc排序_Java实现按照大小写字母顺序排序的方法
  19. RailWay免费容器托管平台
  20. java中IP地址与long之间的转换

热门文章

  1. 10种避免大型部署的方法
  2. Centos 6.x/7.x yum安装php5.6.X
  3. Atitit.研发管理---api版本号策略与版本控制
  4. Spring MVC - 配置Spring MVC
  5. System Center Virtual Machine Manager 2012 SP1系列文章
  6. Jquery的$命名冲突
  7. Nagios监控部署(四)--被监控主机配置
  8. REST API 支持方式
  9. 基于容器的ETCD集群脚本
  10. 【模拟】【codeforces】451B Sort the Array