国庆的最后一天假期,写篇博客纪念一下吧。
实际项目中会有很多页面,而头布局大同小异,如果每个页面都写一遍的话代码太过冗余,所以建议将头布局抽取出来,做一个通用的自定义布局。
首先看一下写完的样式吧:
第一步,先建立一个自定义布局,继承自RelativeLayout(布局文件跟布局是啥就继承啥):
/**
* 自定义头部View
*
* @author jiang zhu on 2019/10/7
*/
public class TitleBar extends RelativeLayout{
public TitleBar(Context context) {
this(context, null);
}
public TitleBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
第二步,写一个通用的布局文件。这里有两种加载方式,可以直接通过new布局之后add View的方式来添加,但是由于添加的布局过多,所以我这里直接建了一个布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@color/colorPrimary"
android:orientation="vertical"
android:paddingTop="20sp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="UselessParent">
<ImageView
android:id="@+id/imgBack"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:contentDescription="@string/app_name"
android:paddingBottom="14dp"
android:paddingTop="14dp"
android:src="@drawable/icon_back"
android:visibility="gone" />
<ImageView
android:id="@+id/imgRight"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"
android:paddingBottom="14dp"
android:paddingTop="14dp"
android:contentDescription="@string/app_name"
android:visibility="gone" />
<TextView
android:id="@+id/txtTitle"
style="@style/txt_titleStyle1"
android:layout_centerInParent="true"
android:text="@string/app_name" />
<TextView
android:id="@+id/txtLeft"
style="@style/txt_titleStyle1"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:text="@string/app_name"
android:textSize="15sp"
android:visibility="gone" />
<TextView
android:id="@+id/txtRight"
style="@style/txt_titleStyle1"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="10dp"
android:textSize="16sp"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
第三步,将布局加载进咱们的自定义布局中:
//加载布局
inflate(mContext, R.layout.layout_title, this);
第四步,将布局中的控件findViewById,之后会有用:
private Context mContext;
private TextView mTitleTv;
private ImageView mImgBack;
private ImageView mImgRight;
private TextView mTxtRight;
/**
* 初始化布局
*/
private void initView() {
//加载布局
inflate(mContext, R.layout.layout_title, this);
//控制头布局,返回关闭页面
mImgBack = findViewById(R.id.imgBack);
//控制标题
mTitleTv = findViewById(R.id.txtTitle);
//右边图片
mImgRight = findViewById(R.id.imgRight);
//右边文字
mTxtRight = findViewById(R.id.txtRight);
mImgBack.setOnClickListener(this);
}
第五步,布局大部分都有返回按钮,如果每个布局都重写,然后设置finish()的话,那就太多了,所以说直接设置好返回按钮的点击事件即可:
@Override
public void onClick(View v) {
if (v.getId() == R.id.imgBack) {
//关闭页面
((Activity) mContext).finish();
}
}
第六步,大家可以看到,在布局中我把返回按钮设为了GONE,所以默认是不显示的,如果需要显示的话还得修改布局,太麻烦了,所以抽出一个公共的方法:
/**
* 设置返回按钮图片是否显示
*
* @param imageVisiable 是否显示
*/
public void setBackImageVisiable(boolean imageVisiable) {
if (imageVisiable){
mImgBack.setVisibility(VISIBLE);
}else {
mImgBack.setVisibility(GONE);
}
}
第七步,每个页面的标题肯定不一样,所以标题肯定需要修改:
/**
* 设置标题栏标题
*
* @param title 标题
*/
public void setTitle(String title) {
mTitleTv.setText(title);
}
第八步,我们也许需要修改返回图片:
/**
* 设置返回按钮图片
*
* @param imageId 图片id
*/
public void setBackImage(int imageId) {
if (imageId!=0){
mImgBack.setImageResource(imageId);
}
}
第九步,设置其他参数的设置方法:
/**
* 设置返回按钮图片是否显示
*
* @param imageVisiable 是否显示
*/
public void setBackImageVisiable(boolean imageVisiable) {
if (imageVisiable){
mImgBack.setVisibility(VISIBLE);
}else {
mImgBack.setVisibility(GONE);
}
}
/**
* 设置右边图片
*
* @param imageId 图片id
*/
public void setRightImage(int imageId) {
if (imageId!=0){
if (mTxtRight.getVisibility() == VISIBLE){
throw new IllegalArgumentException("文字和图片不可同时设置");
}
mImgRight.setVisibility(View.VISIBLE);
mImgRight.setImageResource(imageId);
}
}
/**
* 设置右边文字
*
* @param text 文字
*/
public void setRightText(String text) {
if (text!=null){
if (mImgRight.getVisibility() == VISIBLE){
throw new IllegalArgumentException("文字和图片不可同时设置");
}
mTxtRight.setVisibility(View.VISIBLE);
mTxtRight.setText(text);
}
}
好了,基本上就是这样了,咱们来看一下调用的方式吧:在布局中添加咱们的自定义View:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.zj.titlebar.TitleBar
android:id="@+id/mainTb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="对话框"
android:onClick="createDialog"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后直接在使用的地方进行设置即可:
private void initView() {
mainTb = findViewById(R.id.mainTb);
mainTb.setTitle("我爱你");
}
OK,就这样,如果需要源码的话可以留言联系我。