一般的,在一个app中,会有很多的页面,每个页面都会有一个风格统一的标题栏,包含返回键,标题,右标题或图标,输入栏等。这些相同布局如果在每个activity中都写一次,会变得很繁琐。所以要把它封装成一个自定义控件。
看下效果图
可以选择普通标题和输入框模式,有更多需求可以再自行封装进去。
布局代码
<?xml version="1.0" encoding="utf-8"?>
<!--标题-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_head"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/head_back"
android:layout_width="50dp"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="@+id/iv_head_back"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/icon_back"/>
</LinearLayout>
<TextView
android:id="@+id/head_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/rl_right"
android:layout_toEndOf="@+id/head_back"
android:gravity="center"
android:text="这里是标题"
android:textColor="#E6000000"
android:textSize="18sp" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/head_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/rl_right"
android:layout_centerVertical="true"
android:background="@null"
android:layout_marginHorizontal="10dp"
android:layout_toEndOf="@+id/head_back"
android:visibility="gone"/>
<RelativeLayout
android:id="@+id/rl_right"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true">
<ImageView
android:id="@+id/head_icon_r"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/head_title_r"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#B3000000"
android:textSize="14sp" />
</RelativeLayout>
</RelativeLayout>
布局对应的TitleBar类
package com.example.actionbarsizedemo;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
/**
* 自定义头部标题栏
*/
public class TitleBar extends RelativeLayout {
private static final int DEFAULT = -1;
private RelativeLayout right;
private LinearLayout llBack;
private TextView tvTitle;
private TextView tvTitleR;
private ImageView ivBack;
private ImageView ivRight;
private AppCompatEditText etTitle;
private String textTitle;
private String textRight;
private String editHint;
private int titleSize;
private int colorTitle;
private int colorRight;
private boolean isHideBack;
private int iconBack;
private int iconRight;
private int type;
private OnBackClickListener onBackClickListener;
private OnTitleRClickListener onTitleRClickListener;
public TitleBar(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initHeader(context, attrs);
}
private void initHeader(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.title_bar, this);
right = findViewById(R.id.rl_right);
llBack = findViewById(R.id.head_back);
tvTitle = findViewById(R.id.head_title);
tvTitleR = findViewById(R.id.head_title_r);
ivBack = findViewById(R.id.iv_head_back);
ivRight = findViewById(R.id.head_icon_r);
etTitle = findViewById(R.id.head_et);
onBackClickListener = view -> ((Activity) getContext()).finish();
llBack.setOnClickListener(view ->
onBackClickListener.onBackClickListener(view));
right.setOnClickListener(view -> {
if (onTitleRClickListener != null)
onTitleRClickListener.onTitleRClickListener(view);
});
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TitleBar);
colorTitle = ta.getColor(R.styleable.TitleBar_titleColor, Color.BLACK);
colorRight = ta.getColor(R.styleable.TitleBar_subheadingColor, Color.BLACK);
textTitle = ta.getString(R.styleable.TitleBar_titleText);
editHint = ta.getString(R.styleable.TitleBar_editHint);
textRight = ta.getString(R.styleable.TitleBar_subheadingText);
isHideBack = ta.getBoolean(R.styleable.TitleBar_isHideBack, false);
iconBack = ta.getResourceId(R.styleable.TitleBar_backIconSrc, DEFAULT);
iconRight = ta.getResourceId(R.styleable.TitleBar_rightIconSrc, DEFAULT);
type = ta.getInt(R.styleable.TitleBar_type, 0);
ta.recycle();
tvTitle.setText(textTitle);
tvTitle.setTextColor(colorTitle);
tvTitleR.setText(textRight);
tvTitleR.setTextColor(colorRight);
etTitle.setHint(editHint);
if (iconBack != DEFAULT)
ivBack.setBackgroundResource(iconBack);
if (iconRight != DEFAULT)
ivRight.setBackgroundResource(iconRight);
if (isHideBack)
llBack.setVisibility(INVISIBLE);
if (type == 1) {
tvTitle.setVisibility(GONE);
etTitle.setVisibility(VISIBLE);
}
}
public void setOnBackClickListener(OnBackClickListener onBackClickListener) {
this.onBackClickListener = onBackClickListener;
}
public void setOnTitleRClickListener(OnTitleRClickListener onTitleRClickListener) {
this.onTitleRClickListener = onTitleRClickListener;
}
public void setTitle(String title) {
tvTitle.setText(title);
}
public void setTitle(int id) {
tvTitle.setText(id);
}
public void setTitleR(String titleR) {
tvTitleR.setText(titleR);
}
public void setTitleR(int id) {
tvTitleR.setText(id);
}
public interface OnTitleRClickListener {
void onTitleRClickListener(View view);
}
public interface OnBackClickListener {
void onBackClickListener(View view);
}
}
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 自定义标题栏 -->
<declare-styleable name="TitleBar">
<!-- 标题文字 -->
<attr name="titleText" format="string" />
<!-- 标题颜色 -->
<attr name="titleColor" format="color" />
<!-- 标题大小 -->
<attr name="titleSize" format="dimension" />
<!-- 右标题颜色 -->
<attr name="subheadingColor" format="color" />
<!-- 右标题文字 -->
<attr name="subheadingText" format="string" />
<!-- 是否显示隐藏按钮 -->
<attr name="isHideBack" format="boolean" />
<!-- 返回按钮的图标 -->
<attr name="backIconSrc" format="reference" />
<!-- 右按钮的图标 -->
<attr name="rightIconSrc" format="reference" />
<!-- 标题栏类型,标题/输入框-->
<attr name="type">
<enum name="title" value="0" />
<enum name="input" value="1" />
</attr>
<!-- 输入框hint-->
<attr name="editHint" format="string"/>
</declare-styleable>
</resources>
如何在布局中使用它。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.actionbarsizedemo.TitleBar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:titleText="这里放标题" />
<com.example.actionbarsizedemo.TitleBar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="5dp"
android:background="#000000"
app:backIconSrc="@drawable/icon_back_white"
app:subheadingColor="#CDDC39"
app:subheadingText="副标题"
app:titleColor="#fff"
app:titleText="副标题" />
<com.example.actionbarsizedemo.TitleBar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="10dp"
android:background="#8BC34A"
app:isHideBack="true"
app:titleText="隐藏返回键" />
<com.example.actionbarsizedemo.TitleBar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="10dp"
android:background="#009688"
app:rightIconSrc="@drawable/icon_more"
app:titleColor="#fff"
app:titleText="显示右图标" />
<com.example.actionbarsizedemo.TitleBar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="10dp"
android:background="#FFFFFF"
app:titleColor="#fff"
app:type="input"
app:editHint="请输入关键字"/>
</LinearLayout>
在Activity中设置点击事件等
public class MainActivity extends AppCompatActivity {
private TitleBar tb1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tb1 = findViewById(R.id.tb_1);
tb1.setTitle("代码中设置标题文字");
tb1.setOnTitleRClickListener(view -> {
Toast.makeText(this, "点击了右标题", Toast.LENGTH_SHORT).show();
});
}
}
代码中有使用lambda表达式,需要在gradle中进行相关配置
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
目前最新版本的as(4.1)创建项目会自带此配置