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. Protobuf语言指南

    Protobuf语言指南 l  定义一个消息(message)类型 l  标量值类型 l  Optional 的字段及默认值 l  枚举 l  使用其他消息类型 l  嵌套类型 l  更新一个消息类型 ...

  2. JMX-JAVA进程监控利器

    Java 管理扩展(Java Management Extension,JMX)是从jdk1.4开始的,但从1.5时才加到jdk里面,并把API放到java.lang.management包里面. 如 ...

  3. HDU4578 Transformation 线段树

    这个题让我重新学习了加 乘 在区间的操作 题解:http://blog.csdn.net/guognib/article/details/25324025?utm_source=tuicool& ...

  4. Java8 Stream API

    Stream是Java8中,操作集合的一个重要特性. 从iteration到Stream操作 当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情.举个例子: String co ...

  5. linux扩展权限

    扩展权限包括s,g,t 对于创建文件或文件夹由umask值来决定共默认权限 普通用户默认是0002 root有户是0022 目录的默认权限是777-umask(普通用户775 root是755) 文件 ...

  6. HW5.28

    public class Solution { public static void main(String[] args) { System.out.printf("%s\t%s\n&qu ...

  7. AIDL:Binder invocation to an incorrect interface

    Android进程之间通信异常:主要原因是客户端的aidl文件和与远程调用的Service的aidl文件包名不同 处理方式一般就是在客户端要一个与远程暴露出来的接口包名要一致  服务端: 客户端:

  8. 纯CSS完美实现垂直水平居中的6种方式

    前言 由于HTML语言的定位问题,在网页中实现居中也不是如word中那么简单,尤其在内容样式多变,内容宽高不定的情况下,要实现合理的居中也是颇考验工程师经验的.网上讲居中的文章很多,但是都不太完整,所 ...

  9. 应用web框架模块设计三国演义篇--转至微博

    从事web开发已经10年时间,近几年也一直从事微博应用产品的研发.从原生php写网站到使用cms bbs整合的大型站点,从使用各种流行的开源开发框架到成熟稳定的平台级框架下做研发.这期间对应用型web ...

  10. _doPostBack用法总结

    转载在以下两篇博客: http://www.cnblogs.com/yongtaiyu/archive/2011/05/13/2045746.html http://www.cnblogs.com/F ...