序言
- 现在的程序总体布局一般分为两种:一种是遵循Google的material design风格,一般是顶部toolbar,侧滑菜单之类的,另一种是和IOS类似的底部导航菜单,顶部是自定义的标题栏.两种风格各有特色,谈不上谁好谁坏.程序开发只要遵循其中一种,都能设计出美观的程序,特别是选在4.4以上的系统可以支持沉浸式状态栏,再加上两种设计风格,可以说现在的程序比以前好看很多了.
- 自定义标题栏在网上也有很多教程,可是发现都做得不尽如人意,于是参考网上各位大神的作品,设计出设个自认为还不错的标题栏.封装成一个类,可以在其他项目使用,非常简单.
- 还有一种自定义标题栏是把全部可能用到的图片文字都放进去,再根据需要显示隐藏,这样做虽然也能达到目的,但是设计思想上来说并不太友好
介绍
- 这个标题栏继承自Relativelayout,由左边图片,左边文字,组成标题栏的左边部分,中间文字组成标题栏的中间部分,右边图片和右边文字组成标题栏的右边部分.用户使用的时候只需要根据自身需要设置全部属性或者某些属性即可.同时也做了左边和右边文字图片的监听,比如在某个页面左边是一个箭头,用户可以实现它的监听来达到返回上一页的目的.
先上图
设计步骤
- 在values文件夹下建立一个attr.xml文件,用于存放我们的自定义属性
- 创建CommonToolbar类,继承RelativeLayout.
- 在构造函数中用TypedArray取出自定义属性
- 把这些属性设置到标题栏组件的子控件上
- 把子控件加到标题栏中
- 设置监听接口,实现控件监听
- 在布局文件中使用自定义标题栏
详细步骤
- values文件夹下的attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CommonToolbar">
<!-- 文本的字体大小和颜色-->
<attr name="textColor" format="color"></attr>
<attr name="textSize" format="dimension"></attr>
<!-- 左中右三个文本-->
<attr name="leftText" format="string"></attr>
<attr name="centerText" format="string"></attr>
<attr name="rigtText" format="string"></attr>
<!-- 左右两个图片-->
<attr name="leftImage" format="reference|color"></attr>
<attr name="rightImage" format="reference|color"></attr>
<!-- 包含文本和图片的左右两个线性布局分别距离左边距和右边距的距离-->
<attr name="leftLayoutPading" format="dimension"></attr>
<attr name="rightLayoutPading" format="dimension"></attr>
</declare-styleable>
</resources>
自定义标题栏类:CommonToolbar.java
/**
* Created by KongLingHuaShi on 2015/10/13.
*/
public class CommonToolbar extends RelativeLayout {
LinearLayout leftLayout;
LinearLayout rightLayout;
/**
* 左右两个图片
*/
Drawable leftImage;
Drawable rightImage;
/**
* 左右和中间的文字
*/
String leftText;
String centerText;
String rightText;
/**
* 文字的大小
*/
float textSize;
int textColor;
/***
* 左边图片,右边图片,左边文字,中间文字,右边文字五个控件
*/
ImageView leftIV;
ImageView rightIV;
TextView leftTV;
TextView centerTV;
TextView rightTV;
/**
* 控制左中右三个部分的参数,用来设置布局里面的控件的宽高和位置
*/
LayoutParams leftParams;
LayoutParams centerParams;
LayoutParams rightParams;
/**
* 左右两个线性布局分别距离左边距和右边距的距离
*/
float leftLayoutPading;
float rightLayoutPading;
/**
* 左右两个线性布局的监听接口
*/
ILeftLayoutClickListener leftListener;
IRightLayoutClickListener rightListener;
public CommonToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
//TypedArray用于取出写在values目录下的attr文件下的styleable属性
TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.CommonToolbar);
/**
* 逐个取出
*/
leftImage = t.getDrawable(R.styleable.CommonToolbar_leftImage);
rightImage = t.getDrawable(R.styleable.CommonToolbar_rightImage);
leftText = t.getString(R.styleable.CommonToolbar_leftText);
centerText = t.getString(R.styleable.CommonToolbar_centerText);
rightText = t.getString(R.styleable.CommonToolbar_rigtText);
textSize = t.getDimensionPixelSize(R.styleable.CommonToolbar_textSize, 20);
textColor = t.getColor(R.styleable.CommonToolbar_textColor, Color.WHITE);
leftLayoutPading = t.getDimension(R.styleable.CommonToolbar_leftLayoutPading, 10);
rightLayoutPading = t.getDimension(R.styleable.CommonToolbar_rightLayoutPading, 10);
/**
* 回收TypedArray
*/
t.recycle();
/**
* 实例化子控件
*/
leftIV = new ImageView(context);
rightIV = new ImageView(context);
leftTV = new TextView(context);
centerTV = new TextView(context);
rightTV = new TextView(context);
leftLayout = new LinearLayout(context);
rightLayout = new LinearLayout(context);
/**
* 把取出的属性添加到对应的子控件上
*/
leftIV.setImageDrawable(leftImage);
rightIV.setImageDrawable(rightImage);
leftTV.setText(leftText);
centerTV.setText(centerText);
rightTV.setText(rightText);
leftTV.setTextSize(textSize);
centerTV.setTextSize(textSize);
rightTV.setTextSize(textSize);
leftTV.setTextColor(textColor);
centerTV.setTextColor(textColor);
rightTV.setTextColor(textColor);
//设置中间的文本居中
centerTV.setGravity(Gravity.CENTER);
//设置左边线性布局垂直居中对齐
leftLayout.setGravity(Gravity.CENTER_VERTICAL);
//设置左边线性布局距离左边距的距离,这样做之后会和屏幕形成一定边距,比较美观,但是这时点击段空白区域是没反应的
//因为线性布局不包括这里,如果又要美观又要点这个区域有反应,那只能是设置左边线性布局里面的这第一个控件的边距,而不设置
//线性布局的边距,这样就可以达到效果
leftLayout.setPadding((int) leftLayoutPading, 0, 0, 0);
//leftIV.setPadding((int) leftLayoutPading, 0, 0, 0);
//把左边的Imageview和textview添加到左边线性布局
leftLayout.addView(leftIV);
leftLayout.addView(leftTV);
//把左边线性布局在总布局(整个Toolbar)的大小为WRAP_CONTENT
leftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//把左边线性布局在总布局(整个Toolbar)的左边,并且垂直居中
leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
leftParams.addRule(RelativeLayout.CENTER_VERTICAL);
//把左边线性布局按照leftParams的规则添加到总布局中
addView(leftLayout, leftParams);
//中间文本添加到总布局
centerParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
centerParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(centerTV, centerParams);
//右边线性布局添加到总布局,和左边线性布局一样
rightLayout.setGravity(Gravity.CENTER_VERTICAL);
setPadding(0, 0, (int) rightLayoutPading, 0);
rightLayout.addView(rightTV);
rightLayout.addView(rightIV);
rightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rightParams.addRule(RelativeLayout.CENTER_VERTICAL);
addView(rightLayout, rightParams);
//设置左边布局的监听
if(leftListener!=null){
leftLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
leftListener.leftLayoutClick();
}
});
}
//设置右边布局的监听
if(rightListener!=null)
{
rightLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
rightListener.rightLayoutClick();
}
});
}
}
/***
* 左边布局监听接口
*/
public interface ILeftLayoutClickListener {
public void leftLayoutClick();
}
/**
* 右边布局监听接口
*/
public interface IRightLayoutClickListener {
public void rightLayoutClick();
}
/**
* 给用户调用的左边布局监听接口函数
* @param listener
*/
public void setOnLeftLayoutClickListener(ILeftLayoutClickListener listener) {
this.leftListener = listener;
}
/**
* 给用户调用的右边布局监听接口函数
* @param listener
*/
public void setOnRightLayoutClickListener(IRightLayoutClickListener listener) {
this.rightListener = listener;
}
}
使用
<com.konglinghuashi.taqu.costomview.CommonToolbar
android:id="@+id/commonToolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/basecolor"
costom:leftImage="@mipmap/ic_top_left_message_center_n"
costom:centerText="我"
costom:rightImage="@mipmap/btn_setting_n"
costom:textColor="@color/white"
>
</com.konglinghuashi.taqu.costomview.CommonToolbar>
使用的时候如果是studio,记得加上在布局文件加上:
xmlns:costom=”http://schemas.android.com/apk/res-auto”
如果是eclipse,记得在布局文件加上:
xmlns:costom=”http://schemas.android.com/apk/res/你的总包名”
- 代码注释已经很详细了,但还是说一下流程吧,这样比较好理解
首先我们需要定义用到的组件有左边的ImageView ,左边的Textview ,中间的TextView,右边的ImageView,右边的TextView.最后不好忘了左右两边的ImageView和TextView都是放到一个Linearlayout里面然后再把这两个LinnearLayout放到标题栏上的,所以还需要左右各一个LinnearLayout
定义用来接收自定义属性的变量,比如文字的大小,颜色,图片等等
定义左中右三个LayoutParams,用来设置我们的控件在标题栏的大小和位置
用TypedArray取出attr.xml里面的自定义属性,并且赋值给之前定义好的变量
实例化用到的组件
把取出的属性添加到对应的组件上
设置左边LinnearLayout的控件垂直居中,设置距离左边的边距
把左边的ImageView和TextView添加到左边LinnearLayout
把左边LinnearLayout按照左边LayoutParams的设置添加到标题栏的左边
10.设置右边LinnearLayout的控件垂直居中,设置距离右边的边距
11.把右边的ImageView和TextView添加到右边的LinnearLayout
12.把右边LinnearLayout按照右边LayoutParams的设置添加到标题栏的右边
13.定义监听接口
14.回调监听接口
15.添加两个函数用于给用户调用,实现监听
最后就可以把这个做成一个类库,运用到所有的项目中
不会用csdn的markdown上传文件,只能给出百度云连接了,demo是用andriod studio编写的
demo里面的监听事件忘记加上是否为空判断了,如果没有设置点击事件,可能会点击就崩溃.所以记得加上if(leftListener!=null)和if(rightListener!=null)