Android开发过程中,经常遇到一个项目需要重复的定义相同样式的标题栏,Android相继推出了actionBar, toolBar, 相信有用到的朋友也会遇到一些不如意的时候,比如标题栏居中时,需要自定义xml文件给toolBar等,不了解actionBar,toolBar的可以去找相应的文章了解,这里介绍自定义titleBar满足国内主题风格样式的情况。

为了提前看到效果,先上效果图:

前期准备

1.为标题栏titleView预定义id,在values下的ids.xml中

 <?xml version="1.0" encoding="utf-8"?>
<resources> <item name="tv_title_name" type="id"/>
<item name="tv_left_text" type="id"/>
<item name="iv_left_image" type="id"/>
<item name="iv_right_image" type="id"/>
<item name="iv_right_image_two" type="id"/>
<item name="tv_right_text" type="id"/>
<item name="tv_right_text_two" type="id"/> </resources>

这里可以看到定义了左侧返回按钮id,标题id,后侧按钮id,左侧分两种情况:ImageView/TextView,右侧可以同时存在两个按钮,图片按钮、文字按钮组合。

2.自定义标题栏属性,在valuse下的attr.xml中

 <?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 标题属性 -->
<declare-styleable name="TitleAttr">
<attr name="title_name" format="reference|string"/>
<attr name="title_text_color" format="reference|color"/>
<attr name="title_drawable_right" format="reference"/>
<attr name="title_drawable_left" format="reference"/>
<attr name="title_text_size" format="reference|dimension"/>
<attr name="left_text" format="reference|string"/>
<attr name="left_image" format="reference"/>
<attr name="small_text_size" format="reference|dimension"/>
<attr name="title_gravity">
<enum name="left" value="3"/>
<enum name="center" value="17"/>
<enum name="right" value="5"/>
</attr>
<attr name="right_image" format="reference"/>
<attr name="right_text" format="reference|string"/>
<attr name="right_image_two" format="reference"/>
<attr name="right_text_two" format="reference|string"/>
<attr name="title_height" format="dimension"/>
<attr name="right_text_drawable_right" format="reference"/>
<attr name="right_text_drawable_left" format="reference"/>
<attr name="right_text_two_drawable_right" format="reference"/>
<attr name="right_text_two_drawable_left" format="reference"/>
<attr name="left_text_drawable_right" format="reference"/>
<attr name="left_text_drawable_left" format="reference"/>
</declare-styleable>
</resources>
  • 编码实现
  • 有了前面的准备后,现在就可以开始编码实现了,这里先看看在xml中如何引入我们自定义的控件:
         <com.jarek.library.TitleView
    android:id="@+id/title_main"
    android:layout_width="match_parent"
    android:background="#0093fe"
    title:title_name="标题"
    title:right_text="@string/more"
    title:title_text_color="@android:color/white"
    title:right_image_two="@mipmap/icon_crop_rotate"
    title:title_text_size="20sp"
    title:small_text_size="15sp"
    title:left_text="返回"
    title:left_text_drawable_left="@mipmap/back_normal"
    title:right_text_drawable_right="@mipmap/bar_button_right"
    android:layout_height="50dp"/>

    这里的title标签就是我们自定义,首先创建一个类继承自RelativeLayout,这里选择RelativeLayout作为父类容器,目的在于RelativeLayout便于控制相对位置。 
    首先我们要获得TypedArray对象,所有自定义属性的值通过它来获取:

    TypedArray typeArray = context.obtainStyledAttributes(attrs,     R.styleable.TitleAttr);

    得到了typedArray对象后,就可以开始添加按钮到容器中了,首先看看左边第一个返回按钮如果添加上去,先看代码:

     int leftText =  typeArray.getResourceId(R.styleable.TitleAttr_left_text, 0);
    CharSequence charSequence = leftText > 0 ? typeArray.getResources().getText(leftText) : typeArray.getString(R.styleable.TitleAttr_left_text);

    这里left_text就是自定义属性,表明是左侧TextView显示的文字,文字可以是应用资源文件里的预定义string,也可以是直接输入文字,取到对应的styleable后,首先判断是否大于0,大于0表示是定义在string中的,通过typeArray.getResources().getText()获取值,等于0就直接取值,表示可能是通过直接赋值的方式给值的。取到值后怎么赋值给TextView,这里需要首先给他宽高,这是所有控件都需要的

    /**
    * layout params of RelativeLayout
    * @return LayoutParams
    */
    private LayoutParams initLayoutParams () {
    return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
    }

    我们单独写一个方法,后续就可以直接通过

    LayoutParams params = initLayoutParams();

    来获取预设宽高值了,这里可以看到都是高度填充父控件,宽度是自适应。然后就是new一个TextView了:

    /**
    * create TextView
    * @param context Context
    * @param id the id of TextView
    * @param charSequence text to show
    * @param params relative params
    * @return the TextView which is inited
    */
    @NonNull
    private TextView createTextView(Context context, int id, CharSequence charSequence, LayoutParams params) {
    TextView textView = new TextView(context);
    textView.setLayoutParams(params);
    textView.setGravity(Gravity.CENTER);
    textView.setId(id);
    textView.setMinWidth((int)getPixelSizeByDp(minViewWidth));
    textView.setText(charSequence);
    return textView;
    }

    这里可以看到我们传入了预设的id值,需要显示的内容,以及上面给定的LayoutParams 。创建好TextView后还可以设置TextView的Drawable,通过自定义属性left_text_drawable_right,left_text_drawable_left设置,这里是设置了左右,上下对应的可以设置:

        /**
    * drawable of TextView
    * @param typeArray TypedArray
    * @param leftDrawableStyleable leftDrawableStyleable
    * @param rightDrawableStyleable rightDrawableStyleable
    * @param textView which TextView to set
    */
    private void setTextViewDrawable(TypedArray typeArray, int leftDrawableStyleable, int rightDrawableStyleable, TextView textView) {
    int leftDrawable = typeArray.getResourceId(leftDrawableStyleable, 0);
    int rightDrawable = typeArray.getResourceId(rightDrawableStyleable, 0);
    textView.setCompoundDrawablePadding((int)getPixelSizeByDp(drawablePadding));
    textView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, 0, rightDrawable, 0); }

    这里也是抽取了一个方法出来,然后通过:

    setTextViewDrawable(typeArray, R.styleable.TitleAttr_left_text_drawable_left, R.styleable.TitleAttr_left_text_drawable_right, mLeftBackTextTv);

    即可给指定的TextView设置drawable了。创建好TextView后,前面提到我们用的是相对布局,需要指定位置规则:

    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);

    这里居左显示。同时还可以设置字体大小,通过自定义属性:small_text_size(两侧文字大小),title_text_size(标题文字大小)来设置字体:

        /**
    * get the dimension pixel size from typeArray which is defined in attr
    * @param typeArray TypedArray
    * @param stylable stylable
    * @param defaultSize defaultSize
    * @return the dimension pixel size
    */
    private float getDimensionPixelSize(TypedArray typeArray, int stylable, int defaultSize) {
    int sizeStyleable = typeArray.getResourceId(stylable, 0);
    return sizeStyleable > 0 ? typeArray.getResources().getDimensionPixelSize(sizeStyleable) : typeArray.getDimensionPixelSize(stylable, (int)getPiselSizeBySp(defaultSize));
    }

    一样,这里也是单独写一个方法来做,TypedArray的用法就不多讲了,可以查看其它文章了解。然后通过如下设置字体大小:

         float textSize = getDimensionPixelSize(typeArray, R.styleable.TitleAttr_small_text_size, defaultSmallTextSize);
    mLeftBackTextTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);

    文字颜色,同样的道理:

        /**
    * get textColor
    * @param typeArray TypedArray
    * @return textColor
    */
    private int getTextColorFromAttr (TypedArray typeArray) {
    int textColorStyleable = typeArray.getResourceId(R.styleable.TitleAttr_title_text_color, 0);
    if (textColorStyleable > 0) {
    return typeArray.getResources().getColor(textColorStyleable);
    } else {
    return typeArray.getColor(R.styleable.TitleAttr_title_text_color, textColor);
    } }

    然后调用方法设置颜色:

    mLeftBackTextTv.setTextColor(getTextColorFromAttr(typeArray));

    到这里为止,左侧的第一个文字按钮。或者文字带图片的按钮就创建好了,最后就差一步了:

    mLeftBackTextTv.setTextColor(getTextColorFromAttr(typeArray));

    其它按钮,同样的道理,可以依次添加到容器中,就不多讲了,到此为止我们需要的titleView就创建好了,以后使用就可以直接调用了,不需要每个地方去重复的coding

项目地址:github源码下载

Android自定义标题TitleView的更多相关文章

  1. android 自定义标题

    public class MainActivity extends Activity { /** Called when the activity is first created. */ @Over ...

  2. Android之自定义标题

    我们知道我们创建的每一个Activity,系统默认为我们提供了一下黑色的标题,本篇我将带领大家接触一下如何实现自定义标题样式.相比系统为我们提供的样式,自定义标题可以满足我们唯心所欲的自定义设计,使我 ...

  3. Android 自定义支持快速搜索筛选的选择控件(一)

    Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...

  4. android 自定义view 前的基础知识

    本篇文章是自己自学自定义view前的准备,具体参考资料来自 Android LayoutInflater原理分析,带你一步步深入了解View(一) Android视图绘制流程完全解析,带你一步步深入了 ...

  5. Android 自定义ListView

    本文讲实现一个自定义列表的Android程序,程序将实现一个使用自定义的适配器(Adapter)绑定 数据,通过contextView.setTag绑定数据有按钮的ListView. 系统显示列表(L ...

  6. Android 自定义表格显示数据

    Android 自定义TextView控件,用来组成表格方便数据的展示. 首先看一下效果 样式不是很好看,需要用的可以自己优化一下. 实现方式很简单. 1.自定义控件 MyTableTextView ...

  7. Android 自定义View 三板斧之二——组合现有控件

    通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 上文说过了如何继承现 ...

  8. Android自定义UI模板

    第一步:自定义xml属性 新建一个android项目,在values文件夹中新建一个atts.xml的文件,在这个xml文件中声明我们一会在使用自定义控件时候需要指明的属性.atts.xml < ...

  9. android自定义UI模板图文详解

    不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一 ...

随机推荐

  1. 在MFC[转载]在MFC状态栏显示时间 状态栏显示时间

    原文:在MFC状态栏显示时间,谢小哈皮儿 c/c++ vc 在mfc状态栏显示时间,在VC的控件中有个Status bar可以在窗体状态栏中添加日期和时间.其实通过简单的代码,你就能创建一个有时钟显示 ...

  2. jvm常量池 vsv为什么1000 == 1000返回为False,而100 == 100会返回为True?

    在jvm规范中,每个类型都有自己的常量池.常量池是某类型所用常量的一个有序集合,包括直接常量(基本类型,String)和对其他类型.字段.方法的符号引用.之所以是符号引用而不是像c语言那样,编译时直接 ...

  3. Java面试题:n=2\n1*2*5*6\n--3*4\n\nn=3\n1*2*3*10*11*12\n--4*5*8*9\n----6*7\n如何实现如上结构的数据

    今天学长在面试的时候遇到了一道题,然后让大家做一做. 在不看下面的答案之前,悠闲的朋友们一起来抖动一下大脑吧! 以下是我的想法: import java.util.Scanner;public cla ...

  4. C++中Const说明

    最近在看程序员面试宝典,看到const这块感觉有很大疑惑,查了很多资料,可以总结如下: 1.在C语言中 在C语言中,const修饰的变量不具有常量的特性,只是一个不可修改的变量,实质上仍然是变量,在编 ...

  5. 【暑假】[实用数据结构]UVAlive 3026 Period

    UVAlive 3026 Period 题目: Period   Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld ...

  6. NOIP2007 统计数字

    1.统计数字 (count.pas/c/cpp) [问题描述] 某次科研调查时得到了 n 个自然数,每个数均不超过 1500000000(1.5*109).已知不相同的数 不超过 10000 个,现在 ...

  7. 创建本地CM 离线服务器

    一.包管理工具及CentOS的yum 1.包管理工具如何发现可以用的包 包管理工具依赖一系列软件源,工具下载源的信息存储在配置文件中,其位置随某包管理工具不同而变化 使用yum的RedHat/Cent ...

  8. 最简单的计算MD5方法

    原来写过一个计算MD5的程序,是用了一个叫MD5.pas的单元,使用起来还算简单,但还有更简单的办法,安装了indy就会有IdHashMessageDigest单元(delphi 7默认安装indy) ...

  9. hdoj 2084 数塔

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  10. 【Stage3D学习笔记续】山寨Starling(七):一般优化方法简介及混合模式

    关于事件的优化: 遍历注册的事件由foreach改变为fori,在大量数据遍历时会有提升: 事件池优化: 所有的事件都使用一个对象池进行保存,而不是使用到时进行创建,使用EventDispatcher ...