效果
创建属性文件
<declare-styleable name="TitleBar">
<attr name="leftText" format="string" />
<attr name="rightText" format="string" />
<attr name="title" format="string" />
<attr name="textColor" format="color" />
<attr name="textSize" format="integer" />
<attr name="TitleTextSize" format="integer" />
<attr name="TitleTextColor" format="color" />
</declare-styleable>
创建View类
可以看到这个布局其实比较简单的,思路也就是三个
TextView
,为了使得三个控件的位置控制起来比较方便,我们采用让我们的view
继承自Relativelayout
,这样采用它的空间布局属性可以调整三个控件的位置。然后其中titlebar
中的图标采用icon
的方式加载。下载相应的字体文件和对应的string.xml
。
public class TitleBar extends RelativeLayout {
private String leftText;
private String rightText;
private String title;
private int textColor;
private int textSize;
private int titleTextSize;
private int titleTextColor;
private Typeface font; //字体
public SCITitleBar(Context context) {
this(context,null);
}
public SCITitleBar(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public SCITitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
public void init(Context context, AttributeSet attrs){
// 加载字体
font = Typeface.createFromAsset(context.getAssets(),"Gy.ttf");
// 默认颜色
int defaultColor = ContextCompat.getColor(context,R.color.icons);
// 获取属性
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.SCITitleBar);
leftText = typedArray.getString(R.styleable.SCITitleBar_leftText);
rightText = typedArray.getString(R.styleable.SCITitleBar_rightText);
title = typedArray.getString(R.styleable.SCITitleBar_title);
textColor = typedArray.getColor(R.styleable.SCITitleBar_textColor,defaultColor);
textSize = typedArray.getInt(R.styleable.SCITitleBar_textSize,16);
titleTextSize = typedArray.getInt(R.styleable.SCITitleBar_TitleTextSize,18);
titleTextColor = typedArray.getColor(R.styleable.SCITitleBar_TitleTextColor,defaultColor);
typedArray.recycle();
// 生成控件
TextView leftTextView = new TextView(context);
leftTextView.setText(leftText);
leftTextView.setTextColor(textColor);
leftTextView.setTextSize(textSize);
leftTextView.setTypeface(font);
leftTextView.setGravity(Gravity.CENTER);
leftTextView.setClickable(true);
TextView rightTextView = new TextView(context);
rightTextView.setText(rightText);
rightTextView.setTextColor(textColor);
rightTextView.setGravity(Gravity.CENTER);
rightTextView.setTypeface(font);
rightTextView.setTextSize(textSize);
TextView titleView = new TextView(context);
titleView.setText(title);
titleView.setTextSize(textSize);
titleView.setTextSize(titleTextSize);
titleView.setTypeface(font);
titleView.setTextColor(titleTextColor);
titleView.setGravity(Gravity.CENTER);
// 设置布局信息
LayoutParams leftParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.
MATCH_PARENT);
leftParams.addRule(ALIGN_PARENT_LEFT,TRUE);
leftParams.addRule(Gravity.CENTER_VERTICAL);
leftParams.setMargins(30,0,0,0);
addView(leftTextView, leftParams);
MATCH_PARENT);
rightParams.addRule(ALIGN_PARENT_RIGHT,TRUE);
rightParams.addRule(Gravity.CENTER_VERTICAL);
rightParams.setMargins(0,0,30,0);
addView(rightTextView, rightParams);
LayoutParams titleParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
titleParams.addRule(CENTER_IN_PARENT,TRUE);
titleParams.addRule(CENTER_VERTICAL);
addView(titleView,titleParams);
// todo 添加点击事件
}
}
事件响应
首先创建自定义接口,用接口回调机制简化代码。
public interface TitleBarClickListener {
void onLeftClick();
void onRightClick();
}
然后在我们的自定义
view
类中为我们的左边的TextView
和右边的TextView
绑定点击事件,并添加设置接口参数。
private TitleBarClickListener titleBarClickListener;
public void setTitleBarClickListener(TitleBarClickListener titleBarClickListener) {
this.titleBarClickListener = titleBarClickListener;
}
leftTextView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
titleBarClickListener.onLeftClick();
}
});
rightTextView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
titleBarClickListener.onRightClick();
}
});
使用
在主布局文件中用全类名引用,并使用自定义属性设置样式,即可。绑定事件的时候,只需要给控件实现一个
TitleBarClickListener
的接口,并分别实现里面的两个方法,这两个方法分别对应左右的两个TextView
,因此我们不需要再去考虑是那个TextView
被点击触发啦。
小结
注意在放置内部控件的时候可以使用
RelativeLayout
也可以使用LinearLayout
,只是觉得相对布局更容易实现子控件的位置布局。