最近写了好几个小项目,每个title的设计都是大同小异,左边返回按钮中间标题使用文字或者图片,右边也是文字或者图片。大体都是这样的设计,但是每个界面都要画一遍title说实话真的很烦。
1.先画一个titlebar的布局文件 titlebar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bar_layout"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#51AFF9">
<TextView
android:id="@+id/tv_left_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/tv_middle_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:gravity="center"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/tv_right_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="16dp"
android:gravity="center"
android:textColor="@android:color/white"
android:visibility="visible" />
</RelativeLayout>
2.由于在titlebar中不仅存在文字而且还存在图片,因此我们需要通过TextView的setDrawableLeft去给TextView设置图片,当TextView的Text为空的时候只显示图片
3.在attrs文件中给titlebar定义需要设置参数的一些属性
<declare-styleable name="TitleBar">
<attr name="leftTitle" format="string" />
<attr name="middleTitle" format="string" />
<attr name="rightTitle" format="string" />
<attr name="leftTextSize" format="dimension" />
<attr name="middleTextSize" format="dimension" />
<attr name="rightTextSize" format="dimension" />
<attr name="leftTextColor" format="color" />
<attr name="middleTextColor" format="color" />
<attr name="rightTextColor" format="color" />
<attr name="leftImage" format="integer" />
<attr name="rightImage" format="integer" />
<attr name="tilteBg" format="integer"/>
</declare-styleable>
4.通过继承Relativelayout来实现自定义控件,给Titlebar设置属性
public class Titlebar extends RelativeLayout implements View.OnClickListener {
private String leftTitle;
private String middleTitle;
private String rightTitle;
private int leftTextColor;
private int middleTextColor;
private int rightTextColor;
private int bgColor;
private float leftTextSize;
private float rightTextSize;
private float middleTextSize;
private TextView tvLeft;
private TextView tvMiddle;
private TextView tvRight;
private RelativeLayout rlBg;
private int leftImage;
private int rightImage;
private TitleClickListener listener;
public CustomerTitlebar(Context context) {
super(context);
}
public CustomerTitlebar(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleBar, 0, 0);
initView(array);
array.recycle();
}
public CustomerTitlebar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleBar, defStyleAttr, 0);
initView(array);
array.recycle();
}
private void initView(TypedArray array) {
LayoutInflater.from(getContext()).inflate(R.layout.titlebar_customer, this);
tvLeft = findViewById(R.id.tv_left_title);
tvLeft.setOnClickListener(this);
tvMiddle = findViewById(R.id.tv_middle_title);
tvMiddle.setOnClickListener(this);
tvRight = findViewById(R.id.tv_right_title);
tvRight.setOnClickListener(this);
rlBg = findViewById(R.id.bar_layout);
leftTitle = array.getString(R.styleable.CustomTitleBar_leftTitle);
middleTitle = array.getString(R.styleable.CustomTitleBar_middleTitle);
rightTitle = array.getString(R.styleable.CustomTitleBar_rightTitle);
leftTextColor = array.getColor(R.styleable.CustomTitleBar_leftTextColor, Color.GRAY);
middleTextColor = array.getColor(R.styleable.CustomTitleBar_middleTextColor, Color.TRANSPARENT);
rightTextColor = array.getColor(R.styleable.CustomTitleBar_rightTextColor, Color.GRAY);
bgColor = array.getColor(R.styleable.CustomTitleBar_tilteBg,Color.GRAY);
leftImage = array.getResourceId(R.styleable.CustomTitleBar_leftImage, 0);
rightImage = array.getResourceId(R.styleable.CustomTitleBar_rightImage, 0);
leftTextSize = array.getDimension(R.styleable.CustomTitleBar_leftTextSize, DensityUtil.dip2px(getContext(), 15));
rightTextSize = array.getDimension(R.styleable.CustomTitleBar_rightTextSize, DensityUtil.dip2px(getContext(), 17));
middleTextSize = array.getDimension(R.styleable.CustomTitleBar_middleTextSize, DensityUtil.dip2px(getContext(), 15));
if (leftImage > 0) {
setLeftImage(leftImage);
} else {
setLeftTitle(leftTitle);
}
if (rightImage > 0) {
setRightImage(rightImage);
} else {
setRightTitle(rightTitle);
}
tvLeft.setTextSize(TypedValue.COMPLEX_UNIT_PX, leftTextSize);
tvRight.setTextSize(TypedValue.COMPLEX_UNIT_PX, rightTextSize);
tvMiddle.setTextSize(TypedValue.COMPLEX_UNIT_PX, middleTextSize);
setMiddleTitle(middleTitle);
setLeftTextColor(leftTextColor);
setMiddleTextColor(middleTextColor);
setRightTextColor(rightTextColor);
setTitleBarColor(bgColor);
}
public void setTitleBarColor(int color){
rlBg.setBackgroundColor(color);
}
/**
* @param size 单位sp
*/
public void setLeftTextSize(float size) {
tvLeft.setTextSize(size);
}
/**
* @param size 单位sp
*/
public void setMiddleTextSize(float size) {
tvMiddle.setTextSize(size);
}
/**
* @param size 单位sp
*/
public void setRightTextSize(float size) {
tvRight.setTextSize(size);
}
public void setLeftTextColor(int color) {
tvLeft.setTextColor(color);
}
public void setMiddleTextColor(int color) {
tvMiddle.setTextColor(color);
}
public void setRightTextColor(int color) {
tvRight.setTextColor(color);
}
public void setLeftTitle(String title) {
tvLeft.setText(title);
}
public void setRightTitle(String title) {
tvRight.setText(title);
}
public void setMiddleTitle(String title) {
tvMiddle.setText(title);
}
public void setLeftImage(int leftImage) {
setLeftTitle(leftTitle);
Drawable drawable = getResources().getDrawable(leftImage);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
tvLeft.setCompoundDrawablePadding(DensityUtil.dip2px(getContext(), 8));
tvLeft.setCompoundDrawables(drawable, null, null, null);
}
public void setRightImage(int rightImage) {
setRightTitle(rightTitle);
Drawable drawable = getResources().getDrawable(rightImage);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
tvRight.setCompoundDrawablePadding(DensityUtil.dip2px(getContext(), 8));
tvRight.setCompoundDrawables(null, null, drawable, null);
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.tvLeftTitle) {
if (listener != null) {
listener.onLeftClick();
}
} else if (id == R.id.tvRightTitle) {
if (listener != null) {
listener.onRightClick();
}
}
}
public void setTitleClickListener(TitleClickListener listener) {
this.listener = listener;
}
public interface TitleClickListener {
void onLeftClick();
void onRightClick();
}
}
5.写到这边基本上自定义的titleBar就可以投入使用了,然后就是在使用的layout布局中引用了
<com.victorfactory.commonui.titlebar.Titlebar
android:id="@+id/tablelayout_title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tilteBg = "@color/bg_51AFF9"
app:leftImage="@mipmap/ic_arrow_left"
app:middleTitle= "tablelayout"
app:rightTitle="关闭"
app:middleTextSize = "16sp"
app:rightTextSize = "14sp"
app:middleTextColor = "@color/white"
app:rightTextColor = "@color/white" />
6.在开发的过程中遇到的问题
(1).在自定义titlebar的时候,在写构造函数的时候,把titlebar所有的属性设置都放在了三个参数的的构造函数里面,然后界面一直显示不出来,后面看了资料才清楚原来自定义控件如果设置style的话,会使用三个参数的构造函数,如果只是使用attrs,那么只使就是用两个参数的构造函数
(2).在设置字体大小的时候把COMPLEX_UNIT_PX换成COMPLEX_UNIT_SP的话,整个字体会放大两倍。
/**
* Converts an unpacked complex data value holding a dimension to its final floating
* point value. The two parameters <var>unit</var> and <var>value</var>
* are as in {@link #TYPE_DIMENSION}.
*
* @param unit The unit to convert from.
* @param value The value to apply the unit to.
* @param metrics Current display metrics to use in the conversion --
* supplies display density and scaling information.
*
* @return The complex floating point value multiplied by the appropriate
* metrics depending on its unit.
*/
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
参考了一下源代码,大概意思是根据不同厂商设备,不同分辨率的手机去适配字体的大小。不知道理解的对不对。但是最后还是换回了COMPLEX_NUIT_PX。因为COMPLEX_UNIT_PX在我的手机上显示的字体太大了!