Android 自定义ToolBar并沉浸式
程序员文章站
2023-12-29 18:50:28
...
ToolBar是Android 5.0推出的一个新的导航控件用于取代之前的ActionBar,由于其高度的可定制性、灵活性、具有Material Design风格等优点,越来越多的App也用上了ToolBar。
沉浸式状态栏是从android Kitkat(Android 4.4)开始出现的,它可以被设置成与APP顶部相同的颜色,这就使得切换APP时,整个界面就好似切换到了与APP相同的风格样式一样。
###依赖包:
Toolbar, implementation ‘androidx.appcompat:appcompat:1.1.0’
沉浸式, implementation ‘com.gyf.immersionbar:immersionbar:3.0.0’
1、自定义Toolbar步骤:
1)、定义 /values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TextAppearance_TitleBar_Title" parent="TextAppearance.AppCompat.Toolbar.Title">
...
</style>
<style name="TextAppearance_TitleBar_subTitle" parent="TextAppearance.AppCompat.Toolbar.Subtitle">
....
</style>
</resources>
2)、自定义toolbar 继承 androidx.appcompat.widget.Toolbar
public class CustomToolBar extends Toolbar {
private TextView mCenterTitle;
private ImageView mCenterIcon; //中心icon
private TextView mLeftText;
private ImageButton mLeftIcon;
private TextView mSettingText;
private ImageButton mSettingIcon;
public CustomToolBar(Context context) {
super(context);
}
public CustomToolBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomToolBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setLeftText(@StringRes int id) {
setLeftText(this.getContext().getText(id));
}
public CustomToolBar setLeftText(CharSequence text) {
Context context = this.getContext();
if (this.mLeftText == null) {
this.mLeftText = new TextView(context);
this.mLeftText.setGravity(Gravity.CENTER_VERTICAL);
this.mLeftText.setSingleLine();
// this.mLeftText.setEllipsize(TextUtils.TruncateAt.END);
setLeftTextAppearance(getContext(), R.style.TextAppearance_TitleBar_subTitle);
//textView in left
// this.addMyView(this.mLeftText, Gravity.START);
int i = dp2px(this, 16);
this.addMyView(this.mLeftText, Gravity.START, 0, 0, i, 0, 48);
}
mLeftText.setText(text);
return this;
}
public void setLeftTextAppearance(Context context, @StyleRes int resId) {
if (this.mLeftText != null) {
this.mLeftText.setTextAppearance(context, resId);
}
}
public void setLeftTextColor(@ColorInt int color) {
if (this.mLeftText != null) {
this.mLeftText.setTextColor(color);
}
}
public void setLeftTextOnClickListener(OnClickListener listener) {
if (mLeftText != null) {
mLeftText.setOnClickListener(listener);
}
}
public CustomToolBar setLeftIcon(@DrawableRes int resId) {
return setLeftIcon(ContextCompat.getDrawable(this.getContext(), resId));
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public CustomToolBar setLeftIcon(Drawable drawable) {
Context context = this.getContext();
if (this.mLeftIcon == null) {
this.mLeftIcon = new ImageButton(context);
...
this.addMyView(this.mLeftIcon, Gravity.START);
} else {
if (mLeftIcon.getVisibility() != VISIBLE) {
mLeftIcon.setVisibility(VISIBLE);
}
}
if (mLeftText != null && mLeftText.getVisibility() != GONE) {
mLeftText.setVisibility(GONE);
}
mLeftIcon.setImageDrawable(drawable);
return this;
}
public void setLeftIconOnClickListener(OnClickListener listener) {
if (mLeftIcon != null) {
mLeftIcon.setOnClickListener(listener);
}
}
public void setLeftIconVisibility(int visibility) {
if (mLeftIcon != null) {
mLeftIcon.setVisibility(visibility);
}
}
public CustomToolBar setMyCenterTitle(@StringRes int id, boolean center) {
return setMyCenterTitle(this.getContext().getText(id), center);
}
public void setMyCenterTitle(@StringRes int Rid) {
setMyCenterTitle(this.getContext().getText(Rid));
}
public void setMyCenterTitle(CharSequence text) {
Context context = this.getContext();
if (this.mCenterTitle == null) {
this.mCenterTitle = new TextView(context);
...
} else {
if (this.mCenterTitle.getVisibility() != VISIBLE) {
mCenterTitle.setVisibility(VISIBLE);
}
}
if (mCenterIcon != null && mCenterIcon.getVisibility() != GONE) {
mCenterIcon.setVisibility(GONE);
}
...
}
public CustomToolBar setMyCenterTitle(CharSequence text, boolean center) {
Context context = this.getContext();
if (this.mCenterTitle == null) {
this.mCenterTitle = new TextView(context);
...
} else {
if (this.mCenterTitle.getVisibility() != VISIBLE) {
mCenterTitle.setVisibility(VISIBLE);
}
}
if (mCenterIcon != null && mCenterIcon.getVisibility() != GONE) {
mCenterIcon.setVisibility(GONE);
}
if (!center) {
setTitle(text);
setTitleTextColor(getResources().getColor(R.color.black));
} else {
mCenterTitle.setText(text);
mCenterTitle.setTextColor(getResources().getColor(R.color.black));
mCenterTitle.setTextSize(16);
}
return this;
}
public void setMyCenterTextAppearance(Context context, @StyleRes int resId) {
if (this.mCenterTitle != null) {
this.mCenterTitle.setTextAppearance(context, resId);
}
}
public void setMyCenterTextColor(@ColorInt int color) {
if (this.mCenterTitle != null) {
this.mCenterTitle.setTextColor(color);
}
}
public void setMyCenterTextOnClickListener(OnClickListener listener) {
if (mCenterTitle != null) {
mCenterTitle.setOnClickListener(listener);
}
}
public void setMyCenterIcon(@DrawableRes int resId) {
setMyCenterIcon(ContextCompat.getDrawable(this.getContext(), resId));
}
public void setMyCenterIcon(Drawable drawable) {
Context context = this.getContext();
if (this.mCenterIcon == null) {
...
} else {
if (mCenterIcon.getVisibility() != VISIBLE) {
mCenterIcon.setVisibility(VISIBLE);
}
}
if (mCenterTitle != null && mCenterTitle.getVisibility() != GONE) {
mCenterTitle.setVisibility(GONE);
}
setTitle("");
mCenterIcon.setImageDrawable(drawable);
}
public void setMySettingText(@StringRes int Rid) {
setMySettingText(this.getContext().getText(Rid));
}
public void setMySettingText(CharSequence text) {
Context context = this.getContext();
if (this.mSettingText == null) {
...
} else {
if (mSettingText.getVisibility() != VISIBLE) {
mSettingText.setVisibility(VISIBLE);
}
}
if (mSettingIcon != null && mSettingIcon.getVisibility() != GONE) {
mSettingIcon.setVisibility(GONE);
}
mSettingText.setText(text);
mSettingText.setTextSize(14);
mSettingText.setTextColor(getResources().getColor(R.color.toolbar_title));
}
public void setMySettingTextAppearance(Context context, @StyleRes int resId) {
if (mSettingText != null) {
mSettingText.setTextAppearance(context, resId);
}
}
public void setMySettingTextColor(@ColorInt int color) {
if (mSettingText != null) {
mSettingText.setTextColor(color);
}
}
public void setSettingTextOnClickListener(OnClickListener listener) {
if (mSettingText != null) {
mSettingText.setOnClickListener(listener);
}
}
public CustomToolBar setMySettingIcon(@DrawableRes int resId) {
return setMySettingIcon(ContextCompat.getDrawable(this.getContext(), resId));
// ViewConfiguration.get(this.getContext()).getScaledTouchSlop();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public CustomToolBar setMySettingIcon(Drawable drawable) {
Context context = this.getContext();
if (this.mSettingIcon == null) {
...
} else {
if (mSettingIcon.getVisibility() != VISIBLE) {
mSettingIcon.setVisibility(VISIBLE);
}
}
if (mSettingText != null && mSettingText.getVisibility() != GONE) {
mSettingText.setVisibility(GONE);
}
mSettingIcon.setImageDrawable(drawable);
return this;
}
public void setSettingIconOnClickListener(OnClickListener listener) {
if (mSettingIcon != null) {
mSettingIcon.setOnClickListener(listener);
}
}
private void addSimpleView(View v, int gravity) {
addSimpleView(v, gravity, 0, 0, 0, 0);
}
private void addSimpleView(View v, int gravity, int left, int top, int right, int bottom) {
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, gravity);
lp.setMargins(left, top, right, bottom);
this.addView(v, lp);
}
private void addMyView(View v, int gravity) {
addMyView(v, gravity, 0, 0, dp2px(this, 16), 0);
}
private void addMyView(View v, int gravity, int left, int top, int right, int bottom) {
LayoutParams lp = new LayoutParams(dp2px(this, 20),
dp2px(this, 20), gravity);
lp.setMargins(left, top, right, bottom);
this.addView(v, lp);
}
private void addMyView(View v, int gravity, int left, int top, int right, int bottom, int width) {
LayoutParams lp = new LayoutParams(dp2px(this, width),
20, gravity);
lp.setMargins(left, top, right, bottom);
this.addView(v, lp);
}
public CustomToolBar setCenterTitleWithImg(CharSequence text, Drawable drawable, boolean center) {
Context context = this.getContext();
if (this.mCenterTitle == null) {
this.mCenterTitle = new TextView(context);
...
if (this.mCenterTitle.getVisibility() != VISIBLE) {
mCenterTitle.setVisibility(VISIBLE);
}
}
if (this.mCenterIcon == null) {
this.mCenterIcon = new ImageView(context);
...
} else {
if (mCenterIcon.getVisibility() != VISIBLE) {
mCenterIcon.setVisibility(VISIBLE);
}
}
mCenterTitle.setTextSize(18);
mCenterTitle.setTextColor(getResources().getColor(R.color.black));
mCenterTitle.setText(text);
mCenterIcon.setImageDrawable(drawable);
return this;
}
public void setCenterTitleWithImgOnClickListener(OnClickListener listener) {
if (mCenterTitle != null) {
((View) mCenterTitle.getParent()).setOnClickListener(listener);
}
}
}
2、自定义Toolbar使用
1)、res/layout创建布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.ktx.view.CustomToolBar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="@android:color/white"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:titleTextColor="@android:color/black" />
</FrameLayout>
2)、在布局中使用
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:binding="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.android.playandroid.viewmodel.LoginViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bkg"
android:orientation="vertical">
<include
layout="@layout/title_layout"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
...
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3)、代码中使用
a、初始化:
mBinding.root.toolbar.setNavigationIcon(R.mipmap.register_close)
mBinding.root.toolbar.setMyCenterTitle(getString(R.string.register), true)
mBinding.root.toolbar.setMySettingText(getString(R.string.login))
b、点击事件:
mBinding.root.toolbar.setNavigationOnClickListener {
....
}
mBinding.root.toolbar.setSettingTextOnClickListener {
...
}
4)、沉浸式,设置toolbar背景颜色、文字颜色,一般写在基类
protected open fun initImmersionBar() {
//在BaseActivity里初始化
mImmersionBar = ImmersionBar.with(this)
if (toolbar != null) {
mImmersionBar.titleBar(toolbar)
}
mImmersionBar.statusBarDarkFont(true)
// mImmersionBar.keyboardEnable(true).navigationBarWithKitkatEnable(false).init()
// mImmersionBar.init()
ImmersionBar.with(this).init()
}
Google原生的效果,不必多说,可以实现类似这样的效果
注意:
1、配置整个app的toolbar风格,在/value/styles.xml文件修改代码
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@android:color/white</item>
<item name="colorPrimaryDark">@android:color/white</item>
<item name="colorAccent">@android:color/white</item>
...
</style>
2、修改了 toolbar的高度 ,怎么让navigationIcon显示在toolbar中心?
只要设置如下,即可:android:minHeight="@dimen/toolbar_height"
3、toolbar布局文件位置
如果在commonlibrary目录创建该文件,在app 下还需要复制一份,因为在app 使用toolbar,kotlin-android-extensions引用不到commonlibrary目录下的布局文件。