Skip to content

Commit 087443b

Browse files
committed
修复标题过长在某些机型上面会出现重叠的问题
1 parent e8c2549 commit 087443b

8 files changed

Lines changed: 132 additions & 118 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
* 博客地址:[Android标题栏(TitleBar)绝佳解决方案](https://www.jianshu.com/p/617be02dc265)
66

7-
* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/TitleBar/releases/download/9.6/TitleBar.apk)
7+
* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/TitleBar/releases/download/10.0/TitleBar.apk)
88

99
![](picture/demo_code.png)
1010

@@ -51,7 +51,7 @@ android {
5151
5252
dependencies {
5353
// 标题栏框架:https://github.com/getActivity/TitleBar
54-
implementation 'com.github.getActivity:TitleBar:9.6'
54+
implementation 'com.github.getActivity:TitleBar:10.0'
5555
}
5656
```
5757

app/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
applicationId "com.hjq.bar.demo"
88
minSdkVersion 17
99
targetSdkVersion 31
10-
versionCode 96
11-
versionName "9.6"
10+
versionCode 1000
11+
versionName "10.0"
1212
}
1313

1414
// 支持 JDK 1.8
@@ -61,8 +61,8 @@ dependencies {
6161
implementation 'com.google.android.material:material:1.4.0'
6262

6363
// 吐司工具类:https://github.com/getActivity/ToastUtils
64-
implementation 'com.github.getActivity:ToastUtils:10.5'
64+
implementation 'com.github.getActivity:ToastUtils:11.2'
6565

6666
// 内存泄漏捕捉:https://github.com/square/leakcanary
67-
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
67+
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
6868
}

app/src/main/java/com/hjq/bar/demo/MainActivity.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.hjq.bar.demo;
22

33
import android.os.Bundle;
4-
import android.view.View;
4+
import android.os.Handler;
5+
import android.os.Looper;
56

67
import androidx.appcompat.app.AppCompatActivity;
78

@@ -15,14 +16,16 @@
1516
* time : 2018/08/17
1617
* desc : TitleBar 使用案例
1718
*/
18-
public final class MainActivity extends AppCompatActivity {
19+
public final class MainActivity extends AppCompatActivity implements Runnable {
20+
21+
private static final Handler HANDLER = new Handler(Looper.getMainLooper());
1922

2023
@Override
2124
protected void onCreate(Bundle savedInstanceState) {
2225
super.onCreate(savedInstanceState);
2326
setContentView(R.layout.activity_main);
2427

25-
TitleBar titleBar = findViewById(R.id.tb_main_bar);
28+
TitleBar titleBar = findViewById(R.id.tb_main_bar_click);
2629
titleBar.setOnTitleBarListener(new OnTitleBarListener() {
2730

2831
@Override
@@ -40,5 +43,21 @@ public void onRightClick(TitleBar titleBar) {
4043
ToastUtils.show("右项 View 被点击");
4144
}
4245
});
46+
47+
HANDLER.postDelayed(this, 2000);
48+
}
49+
50+
@Override
51+
public void run() {
52+
TitleBar titleBar = findViewById(R.id.tb_main_bar_long_title);
53+
titleBar.setLeftTitle("左边");
54+
titleBar.setTitle("我是很长很长很长很长很长很长很长很长的标题");
55+
titleBar.setRightTitle("右边");
56+
}
57+
58+
@Override
59+
protected void onDestroy() {
60+
HANDLER.removeCallbacks(this);
61+
super.onDestroy();
4362
}
4463
}

app/src/main/res/layout/activity_main.xml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@
100100
android:layout_width="wrap_content"
101101
android:layout_height="wrap_content"
102102
android:layout_marginTop="20dp"
103-
app:childVerticalPadding="15dp"
104103
app:leftIcon="@null"
105104
app:title="标题向左对齐并且加粗"
106105
app:titleGravity="start"
106+
app:titleHorizontalPadding="20dp"
107107
app:titleStyle="bold" />
108108

109109
<com.hjq.bar.TitleBar
@@ -192,7 +192,7 @@
192192
app:titleSize="20sp" />
193193

194194
<com.hjq.bar.TitleBar
195-
android:id="@+id/tb_main_bar"
195+
android:id="@+id/tb_main_bar_click"
196196
android:layout_width="wrap_content"
197197
android:layout_height="wrap_content"
198198
android:layout_marginTop="20dp"
@@ -320,10 +320,20 @@
320320
android:layout_height="wrap_content"
321321
android:layout_marginTop="20dp"
322322
app:leftIcon="@null"
323-
app:leftTitle="我是很长很长的文案"
324-
app:rightTitle="我是很长很长的文案"
323+
app:leftTitle="我是很长很长很长很长很长的文案"
324+
app:rightTitle="我是很长很长很长很长很长的文案"
325325
app:title="默认的标题栏" />
326326

327+
<com.hjq.bar.TitleBar
328+
android:id="@+id/tb_main_bar_long_title"
329+
android:layout_width="wrap_content"
330+
android:layout_height="wrap_content"
331+
android:layout_marginTop="20dp"
332+
app:leftIcon="@null"
333+
app:leftTitle="我是测试文案我是测试文案我是测试文案"
334+
app:rightTitle="我是测试文案我是测试文案我是测试文案"
335+
app:title="我是很长很长很长很长很长的标题" />
336+
327337
</LinearLayout>
328338

329339
</FrameLayout>

library/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ android {
55

66
defaultConfig {
77
minSdkVersion 16
8-
versionCode 96
9-
versionName "9.6"
8+
versionCode 1000
9+
versionName "10.0"
1010
}
1111

1212
// 支持 JDK 1.8

library/src/main/java/com/hjq/bar/TitleBar.java

Lines changed: 69 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
*/
3030
@SuppressWarnings({"unused", "UnusedReturnValue"})
3131
public class TitleBar extends FrameLayout
32-
implements View.OnClickListener {
32+
implements View.OnClickListener,
33+
View.OnLayoutChangeListener {
3334

3435
private static final String LOG_TAG = "TitleBar";
3536

@@ -274,8 +275,7 @@ public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
274275
addView(mRightView, 2);
275276
addView(mLineView, 3);
276277

277-
addOnLayoutChangeListener(mConstraintChildViewWidthListener);
278-
addOnLayoutChangeListener(mLimitChildViewStatusListener);
278+
addOnLayoutChangeListener(this);
279279

280280
// 如果当前是布局预览模式
281281
if (isInEditMode()) {
@@ -291,6 +291,72 @@ public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
291291
}
292292
}
293293

294+
@Override
295+
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
296+
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
297+
298+
// 如果当前是布局预览模式,避免影响布局预览
299+
if (isInEditMode()) {
300+
return;
301+
}
302+
303+
int titleBarWidth = this.getMeasuredWidth();
304+
int leftViewWidth = mLeftView.getMeasuredWidth();
305+
int centerViewWidth = mTitleView.getMeasuredWidth();
306+
int rightViewWidth = mRightView.getMeasuredWidth();
307+
308+
int maxEdgeWidth = Math.max(leftViewWidth, rightViewWidth);
309+
int calculateTotalWidth = maxEdgeWidth * 2 + centerViewWidth;
310+
// 算出来总宽度是否大于标题栏的宽度
311+
if (calculateTotalWidth <= titleBarWidth) {
312+
return;
313+
}
314+
315+
// 判断是左右项太长还是标题项太长
316+
if (maxEdgeWidth > titleBarWidth / 3) {
317+
// 如果是左右项太长,那么就进行动态计算
318+
measureChildWithMargins(mLeftView, MeasureSpec.makeMeasureSpec(titleBarWidth / 4, MeasureSpec.EXACTLY), 0,
319+
MeasureSpec.makeMeasureSpec(mLeftView.getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
320+
measureChildWithMargins(mTitleView, MeasureSpec.makeMeasureSpec(titleBarWidth / 2, MeasureSpec.EXACTLY), 0,
321+
MeasureSpec.makeMeasureSpec(mTitleView.getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
322+
measureChildWithMargins(mRightView, MeasureSpec.makeMeasureSpec(titleBarWidth / 4, MeasureSpec.EXACTLY), 0,
323+
MeasureSpec.makeMeasureSpec(mRightView.getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
324+
} else {
325+
// 如果是标题项太长,那么就进行动态计算
326+
measureChildWithMargins(mLeftView, MeasureSpec.makeMeasureSpec(maxEdgeWidth, MeasureSpec.EXACTLY), 0,
327+
MeasureSpec.makeMeasureSpec(mLeftView.getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
328+
measureChildWithMargins(mTitleView, MeasureSpec.makeMeasureSpec(titleBarWidth - maxEdgeWidth * 2, MeasureSpec.EXACTLY), 0,
329+
MeasureSpec.makeMeasureSpec(mTitleView.getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
330+
measureChildWithMargins(mRightView, MeasureSpec.makeMeasureSpec(maxEdgeWidth, MeasureSpec.EXACTLY), 0,
331+
MeasureSpec.makeMeasureSpec(mRightView.getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
332+
}
333+
}
334+
335+
@Override
336+
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
337+
// 解决在外部触摸时触发点击效果的问题
338+
if (!mLeftView.isClickable()) {
339+
mLeftView.setClickable(true);
340+
}
341+
if (!mTitleView.isClickable()) {
342+
mTitleView.setClickable(true);
343+
}
344+
if (!mRightView.isClickable()) {
345+
mRightView.setClickable(true);
346+
}
347+
348+
// TextView 里面必须有东西才能被点击
349+
if (!mLeftView.isEnabled()) {
350+
mLeftView.setEnabled(TitleBarSupport.isContainContent(mLeftView));
351+
}
352+
if (!mTitleView.isEnabled()) {
353+
mTitleView.setEnabled(TitleBarSupport.isContainContent(mTitleView));
354+
}
355+
if (!mRightView.isEnabled()) {
356+
mRightView.setEnabled(TitleBarSupport.isContainContent(mRightView));
357+
}
358+
}
359+
294360
/**
295361
* {@link View.OnClickListener}
296362
*/
@@ -880,80 +946,4 @@ public ITitleBarStyle getCurrentStyle() {
880946
public static void setDefaultStyle(ITitleBarStyle style) {
881947
sGlobalStyle = style;
882948
}
883-
884-
private final View.OnLayoutChangeListener mConstraintChildViewWidthListener = new OnLayoutChangeListener() {
885-
886-
@Override
887-
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
888-
// 暂时先移除当前的监听,因为 TextView.setMaxWidth 方法会重新触发监听
889-
removeOnLayoutChangeListener(this);
890-
891-
// 标题栏子 View 最大宽度限制算法
892-
post(() -> {
893-
// 这里要延迟执行,否则会导致子 View.getWidth 的时候为零
894-
int titleBarWidth = right - left;
895-
int leftViewWidth = mLeftView.getWidth();
896-
int centerViewWidth = mTitleView.getWidth();
897-
int rightViewWidth = mRightView.getWidth();
898-
899-
int maxEdgeWidth = Math.max(leftViewWidth, rightViewWidth);
900-
int calculateTotalWidth = maxEdgeWidth * 2 + centerViewWidth;
901-
// 算出来子 View 的宽大于标题栏的宽度
902-
if (calculateTotalWidth >= titleBarWidth) {
903-
// 判断是左右项太长还是标题项太长
904-
if (maxEdgeWidth > titleBarWidth / 3) {
905-
// 如果是左右项太长,那么按照比例进行划分
906-
TitleBarSupport.setMaxWidth(mLeftView, titleBarWidth / 4);
907-
TitleBarSupport.setMaxWidth(mTitleView, titleBarWidth / 2);
908-
TitleBarSupport.setMaxWidth(mRightView, titleBarWidth / 4);
909-
} else {
910-
// 如果是标题项太长,那么就进行动态计算
911-
TitleBarSupport.setMaxWidth(mLeftView, maxEdgeWidth);
912-
TitleBarSupport.setMaxWidth(mTitleView, titleBarWidth - maxEdgeWidth * 2);
913-
TitleBarSupport.setMaxWidth(mRightView, maxEdgeWidth);
914-
}
915-
} else {
916-
// 不限制子 View 的最大宽度
917-
TitleBarSupport.setMaxWidth(mLeftView, Integer.MAX_VALUE);
918-
TitleBarSupport.setMaxWidth(mTitleView, Integer.MAX_VALUE);
919-
TitleBarSupport.setMaxWidth(mRightView, Integer.MAX_VALUE);
920-
}
921-
922-
removeCallbacks(mAddOnLayoutChangeListenerRunnable);
923-
// 这里再次监听需要延迟,否则会导致递归的情况发生
924-
post(mAddOnLayoutChangeListenerRunnable);
925-
});
926-
}
927-
};
928-
929-
@SuppressWarnings("all")
930-
private final View.OnLayoutChangeListener mLimitChildViewStatusListener = new OnLayoutChangeListener() {
931-
932-
@Override
933-
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
934-
// 解决在外部触摸时触发点击效果的问题
935-
if (!mLeftView.isClickable()) {
936-
mLeftView.setClickable(true);
937-
}
938-
if (!mTitleView.isClickable()) {
939-
mTitleView.setClickable(true);
940-
}
941-
if (!mRightView.isClickable()) {
942-
mRightView.setClickable(true);
943-
}
944-
945-
// TextView 里面必须有东西才能被点击
946-
if (!mLeftView.isEnabled()) {
947-
mLeftView.setEnabled(TitleBarSupport.isContainContent(mLeftView));
948-
}
949-
if (!mTitleView.isEnabled()) {
950-
mTitleView.setEnabled(TitleBarSupport.isContainContent(mTitleView));
951-
}
952-
if (!mRightView.isEnabled()) {
953-
mRightView.setEnabled(TitleBarSupport.isContainContent(mRightView));
954-
}
955-
}
956-
};
957-
958-
private final Runnable mAddOnLayoutChangeListenerRunnable = () -> addOnLayoutChangeListener(mConstraintChildViewWidthListener);
959949
}

library/src/main/java/com/hjq/bar/TitleBarSupport.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,4 @@ public static Typeface getTextTypeface(int style) {
211211
return Typeface.DEFAULT;
212212
}
213213
}
214-
215-
/**
216-
* 设置 TextView 的最大宽度
217-
*/
218-
public static void setMaxWidth(TextView view, int maxPixels) {
219-
if (view.getMaxWidth() == maxPixels) {
220-
return;
221-
}
222-
view.setMaxWidth(maxPixels);
223-
}
224214
}

library/src/main/java/com/hjq/bar/style/CommonBarStyle.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,26 @@ public int getChildVerticalPadding(Context context) {
108108
@Override
109109
public CharSequence getTitle(Context context) {
110110
// 如果当前上下文对象是 Activity,就获取 Activity 的 label 属性作为标题栏的标题
111-
if (context instanceof Activity) {
112-
// 获取清单文件中的 android:label 属性值
113-
CharSequence label = ((Activity) context).getTitle();
114-
if (!TextUtils.isEmpty(label)) {
115-
try {
116-
PackageManager packageManager = context.getPackageManager();
117-
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
118-
// 如果当前 Activity 没有设置 android:label 属性,则默认会返回 App 名称,则需要过滤掉
119-
if (!label.toString().equals(packageInfo.applicationInfo.loadLabel(packageManager).toString())) {
120-
// 设置标题
121-
return label;
122-
}
123-
} catch (PackageManager.NameNotFoundException ignored) {}
124-
}
111+
if (!(context instanceof Activity)) {
112+
return "";
113+
}
114+
115+
// 获取清单文件中的 android:label 属性值
116+
CharSequence label = ((Activity) context).getTitle();
117+
if (TextUtils.isEmpty(label)) {
118+
return "";
125119
}
120+
121+
try {
122+
PackageManager packageManager = context.getPackageManager();
123+
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
124+
// 如果当前 Activity 没有设置 android:label 属性,则默认会返回 App 名称,则需要过滤掉
125+
if (!label.toString().equals(packageInfo.applicationInfo.loadLabel(packageManager).toString())) {
126+
// 设置标题
127+
return label;
128+
}
129+
} catch (PackageManager.NameNotFoundException ignored) {}
130+
126131
return "";
127132
}
128133

0 commit comments

Comments
 (0)