实际项目中会有很多页面,而头布局大同小异,如果每个页面都写一遍的话代码太过冗余,所以建议将头布局抽取出来,做一个通用的自定义布局。
首先看一下写完的样式吧:
第一步,先建立一个自定义布局,继承自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("我爱你"); }