前言

在Android应用实际开发中,标题栏是App必不可少的元素之一(当然,不包括游戏),大部分情况下,系统提供的标题栏并不能完全满足我们的需求,就需要手动去编写标题栏布局,那么问题来了,如果是在Activity或者Fragment布局文件里面编写标题栏,那岂不是每一个页面的布局文件都要增加不少的代码,如果想更改一下整个app的标题栏的风格...(十脸蒙蔽),甚至有时候还会可能一个不留神写错了一些属性,导致一些页面的标题栏看起来并不完全一样,用户体验度就悲催了...

需求

那么我们可以通过什么方式来提高我们的效率和质量呢?我想要的效果是这样的:

1.可以在每个Activity或Fragment的布局文件的最外层布局直接使用自定义的标题栏布局,然后其他的内容只需要想以往那样直接写在最外层布局里面,像这样:

2.可以直接在布局文件中声明显示的文字内容,icon素材,标题内容等,而像背景颜色、字体颜色、字体大小就可以统一成一个地方设置,只要更改一个地方,可以方便更改所有标题栏的风格,像这样:

实现

既然定了模样,那就开始来实现这样一个标题栏,首先思考我们需要的属性,一般的标题栏都是左边一个按钮,右边一个按钮,中间一个标题,当然有些情况下不是按钮而是文字,所以我们可以制定多种属性选择,在values下新建一个attrs.xml文件,往里面添加如下属性:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <!--标题栏样式-->
  4. <declare-styleable name="CustomToolBar">
  5. <!--左按钮是否可见|背景-->
  6. <attr name="left_btn_visible" format="boolean"/>
  7. <attr name="left_btn_src" format="reference|color"/>
  8. <!--左文本是否可见|文本内容-->
  9. <attr name="left_tv_visible" format="boolean"/>
  10. <attr name="left_tv_text" format="string"/>
  11. <!--右边按钮是否可见|背景-->
  12. <attr name="right_btn_visible" format="boolean"/>
  13. <attr name="right_btn_src" format="reference|color"/>
  14. <!--右文本是否可见|文本内容-->
  15. <attr name="right_tv_visible" format="boolean"/>
  16. <attr name="right_tv_text" format="string"/>
  17. <!--标题是否可见|文本内容-->
  18. <attr name="title_visible" format="boolean"/>
  19. <attr name="title_text" format="string"/>
  20. <!--背景-->
  21. <attr name="barBackground" format="reference|color"/>
  22. </declare-styleable>
  23. </resources>

定义好了样式之后,开始编写通用的标题栏布局文件

layout_common_toolbar.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content">
  6. <RelativeLayout
  7. android:id="@+id/toolbar_content_rlyt"
  8. android:layout_width="match_parent"
  9. android:layout_height="50dp"
  10. android:paddingLeft="15dp"
  11. android:paddingRight="15dp"
  12. android:background="@color/bg_toolbar">
  13. <Button
  14. android:id="@+id/toolbar_left_btn"
  15. android:layout_width="25dp"
  16. android:layout_height="25dp"
  17. android:layout_alignParentLeft="true"
  18. android:padding="50dp"
  19. android:gravity="center"
  20. android:layout_centerVertical="true"
  21. android:background="@drawable/icon_back"
  22. android:visibility="invisible"/>
  23. <TextView
  24. android:id="@+id/toolbar_left_tv"
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:layout_alignParentLeft="true"
  28. android:gravity="center"
  29. android:layout_centerVertical="true"
  30. android:textColor="#fff"
  31. android:textSize="15sp"
  32. android:text="返回"
  33. android:visibility="gone"
  34. />
  35. <TextView
  36. android:id="@+id/toolbar_title_tv"
  37. android:layout_width="wrap_content"
  38. android:layout_height="match_parent"
  39. android:gravity="center"
  40. android:layout_centerInParent="true"
  41. android:singleLine="true"
  42. android:text="标题"
  43. android:textSize="20sp"
  44. android:textColor="#fff"
  45. android:maxEms="10"
  46. android:visibility="invisible"/>
  47. <Button
  48. android:id="@+id/toolbar_right_btn"
  49. android:layout_width="25dp"
  50. android:layout_height="25dp"
  51. android:layout_alignParentRight="true"
  52. android:gravity="center"
  53. android:layout_centerVertical="true"
  54. android:visibility="invisible"
  55. android:background="#00000000"
  56. android:textSize="15sp"
  57. android:textColor="#fff"/>
  58. <TextView
  59. android:id="@+id/toolbar_right_tv"
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:layout_alignParentRight="true"
  63. android:gravity="center"
  64. android:layout_centerVertical="true"
  65. android:textColor="#fff"
  66. android:textSize="15sp"
  67. android:text="更多"
  68. android:visibility="gone"/>
  69. </RelativeLayout>
  70. <!--标题栏底部微阴影-->
  71. <View
  72. android:layout_width="match_parent"
  73. android:layout_height="0.5dp"
  74. android:background="#AAAAAA"
  75. />
  76. </LinearLayout>

分析:其实就是左Button、左TextView、中间标题TextView、右边Button、右边TextView以及一个底部的细微的阴影效果

属性声明好了,布局文件也写好了,那接下来自然是在自定义类中设置属性值:

我们想要实现将其作为最外层父布局来写,那肯定里面要容纳子控件,可以通过继承LinearLayout来进行自定义,到时候只需直接往里层继续编写子控件布局。

  1. /**
  2. * Created by IT_ZJYANG on 2016/9/9.
  3. * 标题栏
  4. */
  5. public class CustomToolBar extends LinearLayout{
  6. private Boolean isLeftBtnVisible;
  7. private int leftResId;
  8. private Boolean isLeftTvVisible;
  9. private String leftTvText;
  10. private Boolean isRightBtnVisible;
  11. private int rightResId;
  12. private Boolean isRightTvVisible;
  13. private String rightTvText;
  14. private Boolean isTitleVisible;
  15. private String titleText;
  16. private int backgroundResId;
  17. public CustomToolBar(Context context) {
  18. this(context, null);
  19. }
  20. public CustomToolBar(Context context, AttributeSet attrs) {
  21. this(context, attrs, 0);
  22. }
  23. public CustomToolBar(Context context, AttributeSet attrs, int defStyleAttr) {
  24. super(context, attrs, defStyleAttr);
  25. initView(attrs);
  26. }
  27. /**
  28. * 初始化属性
  29. * @param attrs
  30. */
  31. public void initView(AttributeSet attrs){
  32. TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustomToolBar);
  33. /**-------------获取左边按钮属性------------*/
  34. isLeftBtnVisible = typedArray.getBoolean(R.styleable.CustomToolBar_left_btn_visible, false);
  35. leftResId = typedArray.getResourceId(R.styleable.CustomToolBar_left_btn_src, -1);
  36. /**-------------获取左边文本属性------------*/
  37. isLeftTvVisible = typedArray.getBoolean(R.styleable.CustomToolBar_left_tv_visible, false);
  38. if(typedArray.hasValue(R.styleable.CustomToolBar_left_tv_text)){
  39. leftTvText = typedArray.getString(R.styleable.CustomToolBar_left_tv_text);
  40. }
  41. /**-------------获取右边按钮属性------------*/
  42. isRightBtnVisible = typedArray.getBoolean(R.styleable.CustomToolBar_right_btn_visible, false);
  43. rightResId = typedArray.getResourceId(R.styleable.CustomToolBar_right_btn_src, -1);
  44. /**-------------获取右边文本属性------------*/
  45. isRightTvVisible = typedArray.getBoolean(R.styleable.CustomToolBar_right_tv_visible, false);
  46. if(typedArray.hasValue(R.styleable.CustomToolBar_right_tv_text)){
  47. rightTvText = typedArray.getString(R.styleable.CustomToolBar_right_tv_text);
  48. }
  49. /**-------------获取标题属性------------*/
  50. isTitleVisible = typedArray.getBoolean(R.styleable.CustomToolBar_title_visible, false);
  51. if(typedArray.hasValue(R.styleable.CustomToolBar_title_text)){
  52. titleText = typedArray.getString(R.styleable.CustomToolBar_title_text);
  53. }
  54. /**-------------背景颜色------------*/
  55. backgroundResId = typedArray.getResourceId(R.styleable.CustomToolBar_barBackground, -1);
  56. typedArray.recycle();
  57. /**-------------设置内容------------*/
  58. View barLayoutView = View.inflate(getContext(), R.layout.layout_common_toolbar, null);
  59. Button leftBtn = (Button)barLayoutView.findViewById(R.id.toolbar_left_btn);
  60. TextView leftTv = (TextView)barLayoutView.findViewById(R.id.toolbar_left_tv);
  61. TextView titleTv = (TextView)barLayoutView.findViewById(R.id.toolbar_title_tv);
  62. Button rightBtn = (Button)barLayoutView.findViewById(R.id.toolbar_right_btn);
  63. TextView rightTv = (TextView)barLayoutView.findViewById(R.id.toolbar_right_tv);
  64. RelativeLayout barRlyt = (RelativeLayout)barLayoutView.findViewById(R.id.toolbar_content_rlyt);
  65. if(isLeftBtnVisible){
  66. leftBtn.setVisibility(VISIBLE);
  67. }
  68. if(isLeftTvVisible){
  69. leftTv.setVisibility(VISIBLE);
  70. }
  71. if(isRightBtnVisible){
  72. rightBtn.setVisibility(VISIBLE);
  73. }
  74. if(isRightTvVisible){
  75. rightTv.setVisibility(VISIBLE);
  76. }
  77. if(isTitleVisible){
  78. titleTv.setVisibility(VISIBLE);
  79. }
  80. leftTv.setText(leftTvText);
  81. rightTv.setText(rightTvText);
  82. titleTv.setText(titleText);
  83. if(leftResId != -1){
  84. leftBtn.setBackgroundResource(leftResId);
  85. }
  86. if(rightResId != -1){
  87. rightBtn.setBackgroundResource(rightResId);
  88. }
  89. if(backgroundResId != -1){
  90. barRlyt.setBackgroundColor(getResources().getColor(R.color.bg_toolbar));
  91. }
  92. //将设置完成之后的View添加到此LinearLayout中
  93. addView(barLayoutView, 0);
  94. }
  95. }

主要看initView方法,在这个方法中主要做两步:

1.获取我们在实际布局文件(比如Activity的布局文件)中设置的属性的值

2.根据这些值来做相应的操作,比如设置是否可见,设置是选用文字还是选用按钮、标题文本内容等等

思路:可以看到,首先通过inflate获取标题栏layout文件,然后再通过findViewById获取子控件(左Button、右Button、标题TextView等等),再根据我们第一步获取的那些属性值对它们进行相应的设置,最后将设置完成的View通过addView(barLayoutView, 0);将其添加到我们的CustomToolBar中的第一个位置,由于CustomToolBar是继承于LinearLayout,所以标题栏View将会处于最上面的位置,并且以后添加的其他子控件将会依次叠加在标题栏下面(如果CustomToolBar是继承于RelativeLayout,到时候添加内层控件时会被标题栏遮住,不是我们想要的效果)

背景颜色是通过调用资源R.color.bg_toolbar,只需在color.xml中定义:

  1. <!--标题栏颜色-->
  2. <color name="bg_toolbar">#32A082</color>

至于字体大小,也可以用同样的方式抽取到dimen.xml中,然后在layout_common_toolbar.xml中对应的控件下引用即可,如:

运用

完成以上步骤,基本定义好了,接下来就是轻松地调用了:

activity_main.xml

  1. <com.example.zjyang.customtoorbar.CustomToolBar
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. app:left_tv_visible="true"
  9. app:left_tv_text="返回"
  10. app:right_btn_visible="true"
  11. app:right_btn_src="@drawable/icon_search"
  12. app:title_visible="true"
  13. app:title_text="首页"
  14. tools:context="com.example.zjyang.customtoorbar.MainActivity">
  15. <TextView
  16. android:layout_width="match_parent"
  17. android:layout_height="match_parent"
  18. android:gravity="center"
  19. android:layout_gravity="center"
  20. android:text="@string/app_name"
  21. android:textSize="20sp"/>
  22. </com.example.zjyang.customtoorbar.CustomToolBar>

其实在这里无非就是设置自定义属性(是否可见、文本内容),这些都是具体页面所决定的具体内容,而背景颜色等所有标题栏共有的属性则在xml中去配置。

运行效果

其它页面自然同理设置,只需copy过去,修改一下文案和是否可见,就完成了另外一个页面的标题栏,并且高度颜色什么的也保持了相同的规范,修改这个规范也仅仅只是在资源文件中改一下值,有效提高了开发效率和可维护性。

源码:点此下载

Android打造通用标题栏——让你的App统一标题栏风格相关推荐

  1. android app更新弹窗,应用弹窗“此应用专为旧版Android打造,因此可能无法正常运行...”的原因...

    Android P上,有的应用打开时,会弹出对话框,内容:"此应用专为旧版Android打造,因此可能无法正常运行.请尝试检查更新或与开发者联系".用户会感到困惑,真正的原因是什么 ...

  2. Android最新最全100余款开源App(对应Github开源项目)

    最近整理了一些开源的APP,以及对应的一些Github开源项目,现在做一些记录,以便以后查阅. 介绍与链接 BeautifulRefreshLayout-漂亮的美食下拉刷新 https://githu ...

  3. 仿网易新闻APP(三)——标题栏之24小时要闻

    感冒了几天,今天总算正常了点,想了想我还有未完成的最后一类博文,马上就跳起来,接着奋斗了.废话就不多说了先上图看看网易新闻APP的标题栏24小时要闻如下: 我们即将完成的效果图: 图片显示0是默认图片 ...

  4. Android 打造完美的侧滑菜单/侧滑View控件

    概述 Android 打造完美的侧滑菜单/侧滑View控件,完全自定义实现,支持左右两个方向弹出,代码高度简洁流畅,兼容性高,控件实用方便. 详细 代码下载:http://www.demodashi. ...

  5. iOS/Android 微信及浏览器中唤起本地APP

    title: iOS/Android 微信及浏览器中唤起本地APP date: 2017-05-10 10:19:20 tags: 需求概述 分享应用活动链接已经成为手机应用一个非常重要的推广传播形式 ...

  6. Android Studio实现内容丰富的旅游App

    文章目录 一.项目概述 二.开发环境 三.项目结构 四.运行演示 五.项目总结 六.源码获取 一.项目概述 随着人们生活质量的不断提高,外出旅游的需求也日益增多,旅游肯定需要一款App来帮助游客寻找景 ...

  7. 此应用专为旧版Android打造,因此可能无法正常运行。请尝试检查更新或与开发者联系

    最近调试一款新的机型时,出现"此应用专为旧版Android打造,因此可能无法正常运行.请尝试检查更新或与开发者联系"提示,出现这种错误的原因: 应用启动,startActivity ...

  8. 08_android_打造通用svg地图自定义组件

    android_打造通用svg地图自定义组件 一.地图svg数据准备 这里笔者已经整理了云南省16个地州.129个县的svg path数据,如果你要绘制的是其他省份,甚至是中国地图,那么可以从下面这个 ...

  9. 最新web/springboot打造通用的短信验证码微服务(详细)

    前言 很久之前的一篇文章, 最新web/java/jsp实现发送手机短信验证码和邮箱验证码的注册登录功能(详细),截止到目前,依然有很多小伙伴,私信需要帮助,于是我再加一篇,让大家能更好的使用.(当然 ...

  10. 此版本专为旧版android打造,应用弹窗“此应用专为旧版Android打造,因此可能无法正常运行...”的原因...

    Android P上,有的应用打开时,会弹出对话框,内容:"此应用专为旧版Android打造,因此可能无法正常运行.请尝试检查更新或与开发者联系".用户会感到困惑,真正的原因是什么 ...

最新文章

  1. Savitzky-Golay 滤波器详解及C/matlab语言程序设计
  2. 从 Linux 源码看 Socket 的阻塞和非阻塞
  3. 写出完美CSS代码的5个重要方面
  4. python邮件的图片放在哪里_用python保存电子邮件中的嵌入图像
  5. 看看30万码农怎么评论:培训出来的程序员真的很渣吗?
  6. for of 与 for in的区别
  7. javascript的constructor属性介绍
  8. (sn0wbreeze保基带升级,redsnow,absinthe越狱)常用越狱工具下载:redsnow,absinthe,tinyumbrella,sn0wbreeze
  9. 变量命名神器Codelf
  10. 华为机试—拼音翻译成阿拉伯数字(只有数字拼音)
  11. (16)业务数据导入HDFS
  12. java遍历json数据_Java 如何遍历JsonObject对象
  13. 数学上的一些小技巧韩信点兵的问题
  14. uni-app 车牌录入组件封装(支持新能源)
  15. arcgis安装后重启提示 flexnet vendor daemon 交互式服务检测
  16. JavaSE——Day12
  17. C++报错:[Warning] statement has no effect [-Wunused-value]
  18. DSSS信号的分类(周期长码短码与非周期长码)
  19. 从各大顶会看对比学习在句子表征研究进展
  20. 解决微信小程序上传图片不能回显的问题

热门文章

  1. gmap 支持python吗_Python:地图上的标记标签使用gmap.marker_层使用hover_-tex选项不工作...
  2. 23万字 前端HTML与CSS学习笔记总结篇(超详细)
  3. kafka seek方法
  4. 【分享】系统启动项大全
  5. 微观经济学第七周作业(生产函数,规模报酬,投入产出)
  6. 曙光服务器bios开启vt虚拟化,VT开启教程 BIOS开启VT方法
  7. BUUCTF~Misc~Test2
  8. 实话实说 瞧瞧医疗系统集成这些个事儿
  9. 美国计算机工程博士年薪排名,年薪排名
  10. 我的物联网大学【第13章】:王强的逆袭翻身