diff --git a/app/build.gradle b/app/build.gradle index 20fbf94..54ad9a9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,9 +25,9 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.1' + implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation project(':utils') diff --git a/build.gradle b/build.gradle index a00b2e7..9ff2f1d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.4.0" + ext.kotlin_version = "1.4.10" repositories { google() jcenter() diff --git a/utils/src/main/java/com/br3ant/bar/ITitleBarInitializer.java b/utils/src/main/java/com/br3ant/bar/ITitleBarInitializer.java new file mode 100644 index 0000000..dbc8544 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/ITitleBarInitializer.java @@ -0,0 +1,51 @@ +package com.br3ant.bar; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.TextView; + + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2020/08/16 + * desc : 默认初始化器 + */ +public interface ITitleBarInitializer { + + /** + * 获取左标题 View + */ + TextView getLeftView(Context context); + + /** + * 获取中间标题 View + */ + TextView getTitleView(Context context); + + /** + * 获取右标题 View + */ + TextView getRightView(Context context); + + /** + * 获取分割线 View + */ + View getLineView(Context context); + + /** + * 获取标题栏背景 + */ + Drawable getBackgroundDrawable(Context context); + + /** + * 获取子控件的水平内间距 + */ + int getHorizontalPadding(Context context); + + /** + * 获取子控件的垂直内间距 + */ + int getVerticalPadding(Context context); +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/OnTitleBarListener.java b/utils/src/main/java/com/br3ant/bar/OnTitleBarListener.java new file mode 100644 index 0000000..1577ee8 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/OnTitleBarListener.java @@ -0,0 +1,33 @@ +package com.br3ant.bar; + +import android.view.View; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2018/08/20 + * desc : 标题栏点击监听接口 + */ +public interface OnTitleBarListener { + + /** + * 左项被点击 + * + * @param v 被点击的左项View + */ + void onLeftClick(View v); + + /** + * 标题被点击 + * + * @param v 被点击的标题View + */ + void onTitleClick(View v); + + /** + * 右项被点击 + * + * @param v 被点击的右项View + */ + void onRightClick(View v); +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/SelectorDrawable.java b/utils/src/main/java/com/br3ant/bar/SelectorDrawable.java new file mode 100644 index 0000000..5c22217 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/SelectorDrawable.java @@ -0,0 +1,95 @@ +package com.br3ant.bar; + +import android.graphics.drawable.Drawable; +import android.graphics.drawable.StateListDrawable; +import android.os.Build; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2019/03/10 + * desc : 状态选择器构建器 + */ +public final class SelectorDrawable extends StateListDrawable { + + public final static class Builder { + + /** 默认状态 */ + private Drawable mDefault; + /** 焦点状态 */ + private Drawable mFocused; + /** 按下状态 */ + private Drawable mPressed; + /** 选中状态 */ + private Drawable mChecked; + /** 启用状态 */ + private Drawable mEnabled; + /** 选择状态 */ + private Drawable mSelected; + /** 光标悬浮状态(4.0新特性) */ + private Drawable mHovered; + + public Builder setDefault(Drawable drawable) { + mDefault = drawable; + return this; + } + + public Builder setFocused(Drawable drawable) { + mFocused = drawable; + return this; + } + + public Builder setPressed(Drawable drawable) { + mPressed = drawable; + return this; + } + + public Builder setChecked(Drawable drawable) { + mChecked = drawable; + return this; + } + + public Builder setEnabled(Drawable drawable) { + mEnabled = drawable; + return this; + } + + public Builder setSelected(Drawable drawable) { + mSelected = drawable; + return this; + } + + public Builder setHovered(Drawable drawable) { + mHovered = drawable; + return this; + } + + public SelectorDrawable build() { + SelectorDrawable selector = new SelectorDrawable(); + if (mPressed != null) { + selector.addState(new int[]{android.R.attr.state_pressed}, mPressed); + } + if (mFocused != null) { + selector.addState(new int[]{android.R.attr.state_focused}, mFocused); + } + if (mChecked != null) { + selector.addState(new int[]{android.R.attr.state_checked}, mChecked); + } + if (mEnabled != null) { + selector.addState(new int[]{android.R.attr.state_enabled}, mEnabled); + } + if (mSelected != null) { + selector.addState(new int[]{android.R.attr.state_selected}, mSelected); + } + if (mHovered != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + selector.addState(new int[]{android.R.attr.state_hovered}, mHovered); + } + } + if (mDefault != null) { + selector.addState(new int[]{}, mDefault); + } + return selector; + } + } +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/TitleBar.java b/utils/src/main/java/com/br3ant/bar/TitleBar.java new file mode 100644 index 0000000..9007ad0 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/TitleBar.java @@ -0,0 +1,631 @@ +package com.br3ant.bar; + +import android.app.Activity; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.res.TypedArray; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; + +import com.br3ant.bar.initializer.BaseBarInitializer; +import com.br3ant.bar.initializer.LightBarInitializer; +import com.br3ant.bar.initializer.NightBarInitializer; +import com.br3ant.bar.initializer.RippleBarInitializer; +import com.br3ant.bar.initializer.TransparentBarInitializer; +import com.br3ant.utils.R; + + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2018/08/17 + * desc : Android 通用标题栏 + */ +public class TitleBar extends FrameLayout + implements View.OnClickListener, + View.OnLayoutChangeListener { + + /** + * 默认初始化器 + */ + private static ITitleBarInitializer sGlobalInitializer; + /** + * 当前初始化器 + */ + private final ITitleBarInitializer mCurrentInitializer; + + /** + * 监听器对象 + */ + private OnTitleBarListener mListener; + + /** + * 标题栏子 View + */ + private final TextView mLeftView, mTitleView, mRightView; + private final View mLineView; + + /** + * 控件内间距 + */ + private int mHorizontalPadding, mVerticalPadding; + + /** + * 图标显示大小 + */ + private int mDrawableSize = -1; + + public TitleBar(Context context) { + this(context, null, 0); + } + + public TitleBar(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + if (sGlobalInitializer == null) { + sGlobalInitializer = new LightBarInitializer(); + } + + final TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.TitleBar); + + // 标题栏样式设置 + switch (array.getInt(R.styleable.TitleBar_barStyle, 0)) { + case 0x10: + mCurrentInitializer = new LightBarInitializer(); + break; + case 0x20: + mCurrentInitializer = new NightBarInitializer(); + break; + case 0x30: + mCurrentInitializer = new TransparentBarInitializer(); + break; + case 0x40: + mCurrentInitializer = new RippleBarInitializer(); + break; + default: + mCurrentInitializer = TitleBar.sGlobalInitializer; + break; + } + + mLeftView = mCurrentInitializer.getLeftView(context); + mTitleView = mCurrentInitializer.getTitleView(context); + mRightView = mCurrentInitializer.getRightView(context); + mLineView = mCurrentInitializer.getLineView(context); + + // 限制图标显示的大小 + if (array.hasValue(R.styleable.TitleBar_drawableSize)) { + setDrawableSize(array.getDimensionPixelSize(R.styleable.TitleBar_drawableSize, 0)); + } + + // 设置文字和图标之间的间距 + if (array.hasValue(R.styleable.TitleBar_android_drawablePadding)) { + setDrawablePadding(array.getDimensionPixelSize(R.styleable.TitleBar_android_drawablePadding, 0)); + } + + // 标题设置 + if (array.hasValue(R.styleable.TitleBar_leftTitle)) { + setLeftTitle(array.getString(R.styleable.TitleBar_leftTitle)); + } + + if (array.hasValue(R.styleable.TitleBar_title)) { + setTitle(array.getString(R.styleable.TitleBar_title)); + } else { + // 如果当前上下文对象是 Activity,就获取 Activity 的 label 属性作为标题栏的标题 + if (context instanceof Activity) { + // 获取清单文件中的 android:label 属性值 + CharSequence label = ((Activity) context).getTitle(); + if (!TextUtils.isEmpty(label)) { + try { + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); + // 如果当前 Activity 没有设置 android:label 属性,则默认会返回 APP 名称,则需要过滤掉 + if (!label.toString().equals(packageInfo.applicationInfo.loadLabel(packageManager).toString())) { + // 设置标题 + setTitle(label); + } + } catch (PackageManager.NameNotFoundException ignored) { + } + } + } + } + + if (array.hasValue(R.styleable.TitleBar_rightTitle)) { + setRightTitle(array.getString(R.styleable.TitleBar_rightTitle)); + } + + // 图标设置 + if (array.hasValue(R.styleable.TitleBar_leftIcon)) { + setLeftIcon(BaseBarInitializer.getDrawableResources(getContext(), array.getResourceId(R.styleable.TitleBar_leftIcon, 0), array.getColor(R.styleable.TitleBar_leftIconColor, 0))); + } else { + if (!array.getBoolean(R.styleable.TitleBar_backButton, true)) { + // 不显示返回图标 + setLeftIcon(null); + } + } + + if (array.hasValue(R.styleable.TitleBar_rightIcon)) { + setRightIcon(BaseBarInitializer.getDrawableResources(getContext(), array.getResourceId(R.styleable.TitleBar_rightIcon, 0), array.getColor(R.styleable.TitleBar_rightIconColor, 0))); + } + + // 文字颜色设置 + if (array.hasValue(R.styleable.TitleBar_leftColor)) { + setLeftColor(array.getColor(R.styleable.TitleBar_leftColor, 0)); + } + + if (array.hasValue(R.styleable.TitleBar_titleColor)) { + setTitleColor(array.getColor(R.styleable.TitleBar_titleColor, 0)); + } + + if (array.hasValue(R.styleable.TitleBar_rightColor)) { + setRightColor(array.getColor(R.styleable.TitleBar_rightColor, 0)); + } + + // 文字大小设置 + if (array.hasValue(R.styleable.TitleBar_leftSize)) { + setLeftSize(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(R.styleable.TitleBar_leftSize, 0)); + } + + if (array.hasValue(R.styleable.TitleBar_titleSize)) { + setTitleSize(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(R.styleable.TitleBar_titleSize, 0)); + } + + if (array.hasValue(R.styleable.TitleBar_rightSize)) { + setRightSize(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(R.styleable.TitleBar_rightSize, 0)); + } + + // 背景设置 + if (array.hasValue(R.styleable.TitleBar_leftBackground)) { + setLeftBackground(array.getDrawable(R.styleable.TitleBar_leftBackground)); + } + + if (array.hasValue(R.styleable.TitleBar_rightBackground)) { + setRightBackground(array.getDrawable(R.styleable.TitleBar_rightBackground)); + } + + // 分割线设置 + if (array.hasValue(R.styleable.TitleBar_lineColor)) { + setLineDrawable(array.getDrawable(R.styleable.TitleBar_lineColor)); + } + + if (array.hasValue(R.styleable.TitleBar_titleGravity)) { + setTitleGravity(array.getInt(R.styleable.TitleBar_titleGravity, Gravity.NO_GRAVITY)); + } + + if (array.hasValue(R.styleable.TitleBar_titleStyle)) { + setTitleStyle(Typeface.defaultFromStyle(array.getInt(R.styleable.TitleBar_titleStyle, Typeface.NORMAL))); + } + + if (array.hasValue(R.styleable.TitleBar_lineVisible)) { + setLineVisible(array.getBoolean(R.styleable.TitleBar_lineVisible, false)); + } + + if (array.hasValue(R.styleable.TitleBar_lineSize)) { + setLineSize(array.getDimensionPixelSize(R.styleable.TitleBar_lineSize, 0)); + } + + // 如果设置了这两个属性,则将内间距置为空 + if (array.hasValue(R.styleable.TitleBar_android_paddingHorizontal) || array.hasValue(R.styleable.TitleBar_android_paddingVertical)) { + setPadding(0, 0, 0, 0); + } + // 获取子 View 水平内间距 + mHorizontalPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(R.styleable.TitleBar_android_paddingHorizontal, + mCurrentInitializer.getHorizontalPadding(getContext())), getResources().getDisplayMetrics()); + // 获取子 View 垂直内间距 + mVerticalPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(R.styleable.TitleBar_android_paddingVertical, + mCurrentInitializer.getVerticalPadding(getContext())), getResources().getDisplayMetrics()); + + // 回收 TypedArray 对象 + array.recycle(); + + // 设置默认背景 + if (getBackground() == null) { + BaseBarInitializer.setViewBackground(this, mCurrentInitializer.getBackgroundDrawable(context)); + } + + addView(mTitleView, 0); + addView(mLeftView, 1); + addView(mRightView, 2); + addView(mLineView, 3); + + addOnLayoutChangeListener(this); + } + + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + // 先移除当前的监听,因为 setMaxWidth 会重新触发监听 + removeOnLayoutChangeListener(this); + // 标题栏子 View 最大宽度限制算法 + int barWidth = right - left; + int sideWidth = Math.max(mLeftView.getWidth(), mRightView.getWidth()); + int maxWidth = sideWidth * 2 + mTitleView.getWidth(); + // 算出来子 View 的宽大于标题栏的宽度 + if (maxWidth >= barWidth) { + // 判断是左右项太长还是标题项太长 + if (sideWidth > barWidth / 3) { + // 如果是左右项太长,那么按照比例进行划分 + mLeftView.setMaxWidth(barWidth / 4); + mTitleView.setMaxWidth(barWidth / 2); + mRightView.setMaxWidth(barWidth / 4); + } else { + // 如果是标题项太长,那么就进行动态计算 + mLeftView.setMaxWidth(sideWidth); + mTitleView.setMaxWidth(barWidth - sideWidth * 2); + mRightView.setMaxWidth(sideWidth); + } + } else { + // 不限制子 View 的最大宽度 + mLeftView.setMaxWidth(Integer.MAX_VALUE); + mTitleView.setMaxWidth(Integer.MAX_VALUE); + mRightView.setMaxWidth(Integer.MAX_VALUE); + } + + // TextView 里面必须有东西才能被点击 + mLeftView.setEnabled(BaseBarInitializer.checkContainContent(mLeftView)); + mTitleView.setEnabled(BaseBarInitializer.checkContainContent(mTitleView)); + mRightView.setEnabled(BaseBarInitializer.checkContainContent(mRightView)); + + post(new Runnable() { + @Override + public void run() { + // 这里再次监听需要延迟,否则会导致递归的情况发生 + addOnLayoutChangeListener(TitleBar.this); + } + }); + } + + @Override + public void setLayoutParams(ViewGroup.LayoutParams params) { + if (params.width == LayoutParams.WRAP_CONTENT) { + // 如果当前宽度是自适应则转换成占满父布局 + params.width = LayoutParams.MATCH_PARENT; + } + + int horizontalPadding = mHorizontalPadding; + int verticalPadding = 0; + // 如果当前高度是自适应则设置默认的内间距 + if (params.height == ViewGroup.LayoutParams.WRAP_CONTENT) { + verticalPadding = mVerticalPadding; + } + + setChildPadding(horizontalPadding, verticalPadding); + super.setLayoutParams(params); + } + + @Override + protected LayoutParams generateDefaultLayoutParams() { + return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); + } + + /** + * {@link View.OnClickListener} + */ + @Override + public void onClick(View v) { + if (mListener == null) { + return; + } + + if (v == mLeftView) { + mListener.onLeftClick(v); + } else if (v == mRightView) { + mListener.onRightClick(v); + } else if (v == mTitleView) { + mListener.onTitleClick(v); + } + } + + /** + * 设置点击监听器 + */ + public TitleBar setOnTitleBarListener(OnTitleBarListener l) { + mListener = l; + // 设置监听 + mTitleView.setOnClickListener(this); + mLeftView.setOnClickListener(this); + mRightView.setOnClickListener(this); + return this; + } + + /** + * 标题 + */ + public TitleBar setTitle(int id) { + return setTitle(getResources().getString(id)); + } + + public TitleBar setTitle(CharSequence text) { + mTitleView.setText(text); + return this; + } + + public CharSequence getTitle() { + return mTitleView.getText(); + } + + /** + * 左边的标题 + */ + public TitleBar setLeftTitle(int id) { + return setLeftTitle(getResources().getString(id)); + } + + public TitleBar setLeftTitle(CharSequence text) { + mLeftView.setText(text); + return this; + } + + public CharSequence getLeftTitle() { + return mLeftView.getText(); + } + + /** + * 右边的标题 + */ + public TitleBar setRightTitle(int id) { + return setRightTitle(getResources().getString(id)); + } + + public TitleBar setRightTitle(CharSequence text) { + mRightView.setText(text); + return this; + } + + public CharSequence getRightTitle() { + return mRightView.getText(); + } + + /** + * 设置左边的图标 + */ + public TitleBar setLeftIcon(int id) { + return setLeftIcon(BaseBarInitializer.getDrawableResources(getContext(), id,0)); + } + + public TitleBar setLeftIcon(Drawable drawable) { + if (drawable != null) { + if (mDrawableSize != -1) { + drawable.setBounds(0, 0, mDrawableSize, mDrawableSize); + } else { + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + } + } + mLeftView.setCompoundDrawables(drawable, null, null, null); + return this; + } + + public Drawable getLeftIcon() { + return mLeftView.getCompoundDrawables()[0]; + } + + /** + * 设置右边的图标 + */ + public TitleBar setRightIcon(int id) { + return setRightIcon(BaseBarInitializer.getDrawableResources(getContext(), id,0)); + } + + public TitleBar setRightIcon(Drawable drawable) { + if (drawable != null) { + if (mDrawableSize != -1) { + drawable.setBounds(0, 0, mDrawableSize, mDrawableSize); + } else { + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + } + } + mRightView.setCompoundDrawables(null, null, drawable, null); + return this; + } + + public Drawable getRightIcon() { + return mRightView.getCompoundDrawables()[2]; + } + + /** + * 设置左标题颜色 + */ + public TitleBar setLeftColor(int color) { + mLeftView.setTextColor(color); + return this; + } + + /** + * 设置标题颜色 + */ + public TitleBar setTitleColor(int color) { + mTitleView.setTextColor(color); + return this; + } + + /** + * 设置右标题颜色 + */ + public TitleBar setRightColor(int color) { + mRightView.setTextColor(color); + return this; + } + + /** + * 设置左标题状态选择器 + */ + public TitleBar setLeftBackground(int id) { + return setLeftBackground(BaseBarInitializer.getDrawableResources(getContext(), id,0)); + } + + public TitleBar setLeftBackground(Drawable drawable) { + BaseBarInitializer.setViewBackground(mLeftView, drawable); + return this; + } + + /** + * 设置右标题状态选择器 + */ + public TitleBar setRightBackground(int id) { + return setRightBackground(BaseBarInitializer.getDrawableResources(getContext(), id,0)); + } + + public TitleBar setRightBackground(Drawable drawable) { + BaseBarInitializer.setViewBackground(mRightView, drawable); + return this; + } + + /** + * 设置左标题的文本大小 + */ + public TitleBar setLeftSize(int unit, float size) { + mLeftView.setTextSize(unit, size); + return this; + } + + /** + * 设置标题的文本大小 + */ + public TitleBar setTitleSize(int unit, float size) { + mTitleView.setTextSize(unit, size); + return this; + } + + /** + * 设置右标题的文本大小 + */ + public TitleBar setRightSize(int unit, float size) { + mRightView.setTextSize(unit, size); + return this; + } + + /** + * 设置分割线是否显示 + */ + public TitleBar setLineVisible(boolean visible) { + mLineView.setVisibility(visible ? VISIBLE : INVISIBLE); + return this; + } + + /** + * 设置分割线的颜色 + */ + public TitleBar setLineColor(int color) { + return setLineDrawable(new ColorDrawable(color)); + } + + public TitleBar setLineDrawable(Drawable drawable) { + BaseBarInitializer.setViewBackground(mLineView, drawable); + return this; + } + + /** + * 设置分割线的大小 + */ + public TitleBar setLineSize(int px) { + ViewGroup.LayoutParams layoutParams = mLineView.getLayoutParams(); + layoutParams.height = px; + mLineView.setLayoutParams(layoutParams); + return this; + } + + /** + * 设置标题重心 + */ + public TitleBar setTitleGravity(int gravity) { + // 适配 Android 4.2 新特性,布局反方向(开发者选项 - 强制使用从右到左的布局方向) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + gravity = Gravity.getAbsoluteGravity(gravity, getResources().getConfiguration().getLayoutDirection()); + } + mTitleView.setGravity(gravity); + return this; + } + + /** + * 设置标题文字样式 + */ + public TitleBar setTitleStyle(Typeface typeface) { + mTitleView.setTypeface(typeface); + return this; + } + + /** + * 设置图标显示大小 + */ + public TitleBar setDrawableSize(int px) { + mDrawableSize = px; + setLeftIcon(getLeftIcon()); + setRightIcon(getRightIcon()); + return this; + } + + /** + * 设置文字和图标的间距 + */ + public TitleBar setDrawablePadding(int px) { + mLeftView.setCompoundDrawablePadding(px); + mTitleView.setCompoundDrawablePadding(px); + mRightView.setCompoundDrawablePadding(px); + return this; + } + + /** + * 设置子 View 内间距 + */ + public TitleBar setChildPadding(int horizontal, int vertical) { + mLeftView.setPadding(horizontal, vertical, horizontal, vertical); + mTitleView.setPadding(horizontal, vertical, horizontal, vertical); + mRightView.setPadding(horizontal, vertical, horizontal, vertical); + return this; + } + + /** + * 获取左标题View对象 + */ + public TextView getLeftView() { + return mLeftView; + } + + /** + * 获取标题View对象 + */ + public TextView getTitleView() { + return mTitleView; + } + + /** + * 获取右标题View对象 + */ + public TextView getRightView() { + return mRightView; + } + + /** + * 获取分割线View对象 + */ + public View getLineView() { + return mLineView; + } + + /** + * 获取当前的初始化器 + */ + public ITitleBarInitializer getCurrentInitializer() { + return mCurrentInitializer; + } + + /** + * 设置默认初始化器 + */ + public static void setDefaultInitializer(ITitleBarInitializer initializer) { + TitleBar.sGlobalInitializer = initializer; + } +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/initializer/BaseBarInitializer.java b/utils/src/main/java/com/br3ant/bar/initializer/BaseBarInitializer.java new file mode 100644 index 0000000..b520404 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/initializer/BaseBarInitializer.java @@ -0,0 +1,139 @@ +package com.br3ant.bar.initializer; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.core.graphics.drawable.DrawableCompat; + +import com.br3ant.bar.ITitleBarInitializer; + + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2020/09/19 + * desc : 默认初始化器基类 + */ +public abstract class BaseBarInitializer implements ITitleBarInitializer { + + @Override + public TextView getLeftView(Context context) { + TextView leftView = createTextView(context); + leftView.setCompoundDrawablesWithIntrinsicBounds(getBackIcon(context), null, null, null); + leftView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.START)); + leftView.setGravity(Gravity.CENTER_VERTICAL); + leftView.setFocusable(true); + leftView.setSingleLine(); + leftView.setEllipsize(TextUtils.TruncateAt.END); + leftView.setCompoundDrawablePadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, leftView.getResources().getDisplayMetrics())); + leftView.setTextSize(14); + return leftView; + } + + @Override + public TextView getTitleView(Context context) { + TextView titleView = createTextView(context); + titleView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER_HORIZONTAL)); + titleView.setGravity(Gravity.CENTER); + titleView.setFocusable(true); + titleView.setSingleLine(); + // 给标题设置跑马灯效果(仅在标题过长的时候才会显示) + titleView.setEllipsize(TextUtils.TruncateAt.MARQUEE); + // 设置跑马灯的循环次数 + titleView.setMarqueeRepeatLimit(-1); + // 设置跑马灯之后需要设置选中才能有效果 + titleView.setSelected(true); + titleView.setCompoundDrawablePadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, titleView.getResources().getDisplayMetrics())); + titleView.setTextSize(16); + return titleView; + } + + @Override + public TextView getRightView(Context context) { + TextView rightView = createTextView(context); + rightView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.END)); + rightView.setGravity(Gravity.CENTER_VERTICAL); + rightView.setFocusable(true); + rightView.setSingleLine(); + rightView.setEllipsize(TextUtils.TruncateAt.END); + rightView.setCompoundDrawablePadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, rightView.getResources().getDisplayMetrics())); + rightView.setTextSize(14); + return rightView; + } + + @Override + public View getLineView(Context context) { + View lineView = new View(context); + lineView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1, Gravity.BOTTOM)); + return lineView; + } + + @Override + public int getHorizontalPadding(Context context) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, context.getResources().getDisplayMetrics()); + } + + @Override + public int getVerticalPadding(Context context) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, context.getResources().getDisplayMetrics()); + } + + public abstract Drawable getBackIcon(Context context); + + protected TextView createTextView(Context context) { + return new TextView(context); + } + + /** + * 获取图片资源 + */ + public static Drawable getDrawableResources(Context context, int id, int tint) { + Drawable drawable; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + drawable = context.getResources().getDrawable(id, context.getTheme()).mutate(); + } else { + drawable = context.getResources().getDrawable(id).mutate(); + } + if (tint != 0) { + drawable = DrawableCompat.wrap(drawable); + DrawableCompat.setTint(drawable, tint); + } + return drawable; + } + + /** + * 设置 View 背景 + */ + public static void setViewBackground(View view, Drawable drawable) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.setBackground(drawable); + } else { + view.setBackgroundDrawable(drawable); + } + } + + /** + * 检查 TextView 是否包含内容 + */ + public static boolean checkContainContent(TextView textView) { + CharSequence text = textView.getText(); + if (!TextUtils.isEmpty(text)) { + return true; + } + Drawable[] drawables = textView.getCompoundDrawables(); + for (Drawable drawable : drawables) { + if (drawable != null) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/initializer/LightBarInitializer.java b/utils/src/main/java/com/br3ant/bar/initializer/LightBarInitializer.java new file mode 100644 index 0000000..cef56d3 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/initializer/LightBarInitializer.java @@ -0,0 +1,68 @@ +package com.br3ant.bar.initializer; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.TextView; + +import com.br3ant.bar.SelectorDrawable; +import com.br3ant.utils.R; + + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2020/09/19 + * desc : 日间主题样式实现(布局属性:app:barStyle="light") + */ +public class LightBarInitializer extends BaseBarInitializer { + + @Override + public TextView getLeftView(Context context) { + TextView leftView = super.getLeftView(context); + leftView.setTextColor(0xFF666666); + setViewBackground(leftView, new SelectorDrawable.Builder() + .setDefault(new ColorDrawable(0x00000000)) + .setFocused(new ColorDrawable(0x0C000000)) + .setPressed(new ColorDrawable(0x0C000000)) + .build()); + return leftView; + } + + @Override + public TextView getTitleView(Context context) { + TextView titleView = super.getTitleView(context); + titleView.setTextColor(0xFF222222); + return titleView; + } + + @Override + public TextView getRightView(Context context) { + TextView rightView = super.getRightView(context); + rightView.setTextColor(0xFFA4A4A4); + setViewBackground(rightView, new SelectorDrawable.Builder() + .setDefault(new ColorDrawable(0x00000000)) + .setFocused(new ColorDrawable(0x0C000000)) + .setPressed(new ColorDrawable(0x0C000000)) + .build()); + return rightView; + } + + @Override + public View getLineView(Context context) { + View lineView = super.getLineView(context); + setViewBackground(lineView, new ColorDrawable(0xFFECECEC)); + return lineView; + } + + @Override + public Drawable getBackIcon(Context context) { + return getDrawableResources(context, R.drawable.bar_arrows_left_black,0); + } + + @Override + public Drawable getBackgroundDrawable(Context context) { + return new ColorDrawable(0xFFFFFFFF); + } +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/initializer/NightBarInitializer.java b/utils/src/main/java/com/br3ant/bar/initializer/NightBarInitializer.java new file mode 100644 index 0000000..f2217ae --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/initializer/NightBarInitializer.java @@ -0,0 +1,68 @@ +package com.br3ant.bar.initializer; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.TextView; + +import com.br3ant.bar.SelectorDrawable; +import com.br3ant.utils.R; + + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2020/09/19 + * desc : 夜间主题样式实现(布局属性:app:barStyle="night") + */ +public class NightBarInitializer extends BaseBarInitializer { + + @Override + public TextView getLeftView(Context context) { + TextView leftView = super.getLeftView(context); + leftView.setTextColor(0xCCFFFFFF); + setViewBackground(leftView, new SelectorDrawable.Builder() + .setDefault(new ColorDrawable(0x00000000)) + .setFocused(new ColorDrawable(0x66FFFFFF)) + .setPressed(new ColorDrawable(0x66FFFFFF)) + .build()); + return leftView; + } + + @Override + public TextView getTitleView(Context context) { + TextView titleView = super.getTitleView(context); + titleView.setTextColor(0xEEFFFFFF); + return titleView; + } + + @Override + public TextView getRightView(Context context) { + TextView rightView = super.getRightView(context); + rightView.setTextColor(0xCCFFFFFF); + setViewBackground(rightView, new SelectorDrawable.Builder() + .setDefault(new ColorDrawable(0x00000000)) + .setFocused(new ColorDrawable(0x66FFFFFF)) + .setPressed(new ColorDrawable(0x66FFFFFF)) + .build()); + return rightView; + } + + @Override + public View getLineView(Context context) { + View lineView = super.getLineView(context); + setViewBackground(lineView, new ColorDrawable(0xFFFFFFFF)); + return lineView; + } + + @Override + public Drawable getBackIcon(Context context) { + return getDrawableResources(context, R.drawable.bar_arrows_left_white,0); + } + + @Override + public Drawable getBackgroundDrawable(Context context) { + return new ColorDrawable(0xFF000000); + } +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/initializer/RippleBarInitializer.java b/utils/src/main/java/com/br3ant/bar/initializer/RippleBarInitializer.java new file mode 100644 index 0000000..e284006 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/initializer/RippleBarInitializer.java @@ -0,0 +1,46 @@ +package com.br3ant.bar.initializer; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.TypedValue; +import android.widget.TextView; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2020/09/19 + * desc : 水波纹样式实现(布局属性:app:barStyle="ripple") + */ +public class RippleBarInitializer extends TransparentBarInitializer { + + @Override + public TextView getLeftView(Context context) { + TextView leftView = super.getLeftView(context); + Drawable drawable = getRippleDrawable(context); + if (drawable != null) { + setViewBackground(leftView, drawable); + } + return leftView; + } + + @Override + public TextView getRightView(Context context) { + TextView rightView = super.getRightView(context); + Drawable drawable = getRippleDrawable(context); + if (drawable != null) { + setViewBackground(rightView, drawable); + } + return rightView; + } + + /** + * 获取水波纹的点击效果 + */ + public Drawable getRippleDrawable(Context context) { + TypedValue typedValue = new TypedValue(); + if (context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, typedValue, true)) { + return getDrawableResources(context, typedValue.resourceId,0); + } + return null; + } +} \ No newline at end of file diff --git a/utils/src/main/java/com/br3ant/bar/initializer/TransparentBarInitializer.java b/utils/src/main/java/com/br3ant/bar/initializer/TransparentBarInitializer.java new file mode 100644 index 0000000..9a396c9 --- /dev/null +++ b/utils/src/main/java/com/br3ant/bar/initializer/TransparentBarInitializer.java @@ -0,0 +1,69 @@ +package com.br3ant.bar.initializer; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.TextView; + +import com.br3ant.bar.SelectorDrawable; +import com.br3ant.utils.R; + + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/TitleBar + * time : 2020/09/19 + * desc : 透明主题样式实现(布局属性:app:barStyle="transparent") + */ +public class TransparentBarInitializer extends BaseBarInitializer { + + @Override + public TextView getLeftView(Context context) { + TextView leftView = super.getLeftView(context); + leftView.setTextColor(0xFFFFFFFF); + setViewBackground(leftView, new SelectorDrawable.Builder() + .setDefault(new ColorDrawable(0x00000000)) + .setFocused(new ColorDrawable(0x22000000)) + .setPressed(new ColorDrawable(0x22000000)) + .build()); + return leftView; + } + + @Override + public TextView getTitleView(Context context) { + TextView titleView = super.getTitleView(context); + titleView.setTextColor(0xFFFFFFFF); + return titleView; + } + + @Override + public TextView getRightView(Context context) { + TextView rightView = super.getRightView(context); + rightView.setTextColor(0xFFFFFFFF); + setViewBackground(rightView, new SelectorDrawable.Builder() + .setDefault(new ColorDrawable(0x00000000)) + .setFocused(new ColorDrawable(0x22000000)) + .setPressed(new ColorDrawable(0x22000000)) + .build()); + return rightView; + } + + @Override + public View getLineView(Context context) { + View lineView = super.getLineView(context); + setViewBackground(lineView, new ColorDrawable(0xFFECECEC)); + lineView.setVisibility(View.INVISIBLE); + return lineView; + } + + @Override + public Drawable getBackIcon(Context context) { + return getDrawableResources(context, R.drawable.bar_arrows_left_white,0); + } + + @Override + public Drawable getBackgroundDrawable(Context context) { + return new ColorDrawable(0x00000000); + } +} \ No newline at end of file diff --git a/utils/src/main/res/drawable/bar_arrows_left_black.xml b/utils/src/main/res/drawable/bar_arrows_left_black.xml new file mode 100644 index 0000000..b633e78 --- /dev/null +++ b/utils/src/main/res/drawable/bar_arrows_left_black.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/utils/src/main/res/drawable/bar_arrows_left_white.xml b/utils/src/main/res/drawable/bar_arrows_left_white.xml new file mode 100644 index 0000000..4add8ff --- /dev/null +++ b/utils/src/main/res/drawable/bar_arrows_left_white.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/utils/src/main/res/values/attrs.xml b/utils/src/main/res/values/attrs.xml new file mode 100644 index 0000000..bc38ca2 --- /dev/null +++ b/utils/src/main/res/values/attrs.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file