diff --git a/android/app/src/main/java/com/hyzq/boss/BossUi.java b/android/app/src/main/java/com/hyzq/boss/BossUi.java
index b588fc2..27f5b93 100644
--- a/android/app/src/main/java/com/hyzq/boss/BossUi.java
+++ b/android/app/src/main/java/com/hyzq/boss/BossUi.java
@@ -1145,6 +1145,7 @@ public final class BossUi {
TextView kindView = new TextView(context);
kindView.setText(kindLabel);
kindView.setTextSize(11);
+ kindView.setIncludeFontPadding(false);
kindView.setTypeface(Typeface.DEFAULT_BOLD);
kindView.setTextColor(context.getColor(outgoing ? R.color.boss_surface : R.color.boss_text_muted));
kindView.setPadding(0, 0, 0, dp(context, 6));
@@ -1154,7 +1155,8 @@ public final class BossUi {
TextView bodyView = new TextView(context);
bodyView.setText(BossMarkdown.render(context, body, outgoing));
bodyView.setTextSize(14);
- bodyView.setLineSpacing(0f, 1.34f);
+ bodyView.setIncludeFontPadding(false);
+ bodyView.setLineSpacing(0f, 1.26f);
bodyView.setTextColor(context.getColor(outgoing ? R.color.boss_surface : R.color.boss_text_primary));
bodyView.setMaxWidth(maxBubbleWidth);
bodyView.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
@@ -2275,6 +2277,7 @@ public final class BossUi {
String metaText = buildMessageMetaText(senderLabel, meta, outgoing);
metaView.setText(metaText);
metaView.setTextSize(11);
+ metaView.setIncludeFontPadding(false);
metaView.setTextColor(context.getColor(R.color.boss_text_soft));
metaView.setPadding(dp(context, 6), 0, dp(context, 6), dp(context, 4));
wrapper.addView(metaView);
@@ -2472,6 +2475,7 @@ public final class BossUi {
String metaText = buildMessageMetaText(senderLabel, meta, outgoing);
metaView.setText(metaText);
metaView.setTextSize(11);
+ metaView.setIncludeFontPadding(false);
metaView.setTextColor(context.getColor(R.color.boss_text_soft));
metaView.setPadding(dp(context, 6), 0, dp(context, 6), dp(context, 4));
wrapper.addView(metaView);
diff --git a/android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java b/android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java
index b719e54..596536e 100644
--- a/android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java
+++ b/android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java
@@ -1333,16 +1333,16 @@ public class ProjectDetailActivity extends BossScreenActivity {
private Button buildQuickActionButton(String label, boolean highlight) {
Button button = new Button(this);
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, BossUi.dp(this, 40), 1f);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, BossUi.dp(this, 36), 1f);
if (quickActionsLayout.getChildCount() > 0) {
- params.leftMargin = BossUi.dp(this, 8);
+ params.leftMargin = BossUi.dp(this, 6);
}
button.setLayoutParams(params);
button.setMinWidth(0);
button.setText(label);
- button.setTextSize(14);
+ button.setTextSize(13);
button.setAllCaps(false);
- button.setPadding(BossUi.dp(this, 12), 0, BossUi.dp(this, 12), 0);
+ button.setPadding(BossUi.dp(this, 10), 0, BossUi.dp(this, 10), 0);
button.setBackgroundResource(highlight ? R.drawable.bg_primary_button : R.drawable.bg_secondary_button);
button.setTextColor(getColor(highlight ? R.color.boss_surface : R.color.boss_text_primary));
return button;
diff --git a/android/app/src/main/res/layout/activity_conversation_info.xml b/android/app/src/main/res/layout/activity_conversation_info.xml
index 72f6f44..addcddd 100644
--- a/android/app/src/main/res/layout/activity_conversation_info.xml
+++ b/android/app/src/main/res/layout/activity_conversation_info.xml
@@ -37,8 +37,11 @@
diff --git a/android/app/src/main/res/layout/activity_forward_target.xml b/android/app/src/main/res/layout/activity_forward_target.xml
index e1202bf..e52aab2 100644
--- a/android/app/src/main/res/layout/activity_forward_target.xml
+++ b/android/app/src/main/res/layout/activity_forward_target.xml
@@ -37,8 +37,11 @@
diff --git a/android/app/src/main/res/layout/activity_group_create.xml b/android/app/src/main/res/layout/activity_group_create.xml
index 81aa0c2..e9a530f 100644
--- a/android/app/src/main/res/layout/activity_group_create.xml
+++ b/android/app/src/main/res/layout/activity_group_create.xml
@@ -37,8 +37,11 @@
diff --git a/android/app/src/main/res/layout/activity_group_info.xml b/android/app/src/main/res/layout/activity_group_info.xml
index 1e655e3..f956f2e 100644
--- a/android/app/src/main/res/layout/activity_group_info.xml
+++ b/android/app/src/main/res/layout/activity_group_info.xml
@@ -37,8 +37,11 @@
diff --git a/android/app/src/main/res/layout/activity_project_chat.xml b/android/app/src/main/res/layout/activity_project_chat.xml
index 5f6dbc6..d03161f 100644
--- a/android/app/src/main/res/layout/activity_project_chat.xml
+++ b/android/app/src/main/res/layout/activity_project_chat.xml
@@ -40,6 +40,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
+ android:includeFontPadding="false"
android:maxLines="1"
android:text="项目详情"
android:textColor="@color/boss_text_primary"
@@ -48,9 +49,12 @@
@@ -103,9 +107,9 @@
android:background="@color/boss_bg_app"
android:orientation="vertical"
android:paddingLeft="12dp"
- android:paddingTop="10dp"
+ android:paddingTop="8dp"
android:paddingRight="12dp"
- android:paddingBottom="12dp">
+ android:paddingBottom="8dp">
+ android:paddingBottom="10dp">
@@ -199,23 +203,25 @@
android:hint="输入消息"
android:inputType="textCapSentences|textMultiLine"
android:maxLines="4"
- android:minHeight="44dp"
- android:paddingLeft="14dp"
- android:paddingTop="10dp"
- android:paddingRight="14dp"
- android:paddingBottom="10dp"
+ android:minHeight="40dp"
+ android:paddingLeft="12dp"
+ android:paddingTop="8dp"
+ android:paddingRight="12dp"
+ android:paddingBottom="8dp"
android:textColor="@color/boss_text_primary"
- android:textColorHint="@color/boss_text_muted" />
+ android:textColorHint="@color/boss_text_muted"
+ android:textSize="14sp" />
@@ -227,32 +233,34 @@
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="12dp"
- android:paddingTop="10dp"
+ android:paddingTop="8dp"
android:paddingRight="12dp"
- android:paddingBottom="12dp"
+ android:paddingBottom="10dp"
android:visibility="gone">
diff --git a/android/app/src/main/res/layout/activity_screen.xml b/android/app/src/main/res/layout/activity_screen.xml
index c08d343..3b850db 100644
--- a/android/app/src/main/res/layout/activity_screen.xml
+++ b/android/app/src/main/res/layout/activity_screen.xml
@@ -40,6 +40,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
+ android:includeFontPadding="false"
android:maxLines="1"
android:text="标题"
android:textColor="@color/boss_text_primary"
@@ -52,6 +53,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
+ android:includeFontPadding="false"
android:maxLines="1"
android:text="副标题"
android:textColor="@color/boss_text_muted"
diff --git a/android/app/src/test/java/com/hyzq/boss/BossUiMessageBubbleTest.java b/android/app/src/test/java/com/hyzq/boss/BossUiMessageBubbleTest.java
index f8851ba..ce12aa7 100644
--- a/android/app/src/test/java/com/hyzq/boss/BossUiMessageBubbleTest.java
+++ b/android/app/src/test/java/com/hyzq/boss/BossUiMessageBubbleTest.java
@@ -1,5 +1,7 @@
package com.hyzq.boss;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.content.Context;
@@ -38,4 +40,28 @@ public class BossUiMessageBubbleTest {
assertTrue(bodyView.getText().toString().contains("重点"));
assertTrue(bodyView.getText().toString().contains("代码"));
}
+
+ @Test
+ public void buildMessageBubble_usesWechatCompactTextMetrics() {
+ Context context = RuntimeEnvironment.getApplication();
+
+ LinearLayout wrapper = BossUi.buildMessageBubble(
+ context,
+ "线程",
+ "这是一条普通对话内容",
+ "10:26",
+ false,
+ "结果"
+ );
+
+ TextView metaView = (TextView) wrapper.getChildAt(0);
+ LinearLayout bubble = (LinearLayout) wrapper.getChildAt(1);
+ TextView kindView = (TextView) bubble.getChildAt(0);
+ TextView bodyView = (TextView) bubble.getChildAt(1);
+
+ assertFalse("消息时间/发送人不应保留默认字体留白", metaView.getIncludeFontPadding());
+ assertFalse("消息类型标签不应保留默认字体留白", kindView.getIncludeFontPadding());
+ assertFalse("消息正文不应保留默认字体留白", bodyView.getIncludeFontPadding());
+ assertEquals("消息正文应对标微信聊天正文", 14f, bodyView.getTextSize() / context.getResources().getDisplayMetrics().scaledDensity, 0.5f);
+ }
}
diff --git a/android/app/src/test/java/com/hyzq/boss/ProjectDetailActivityUiTest.java b/android/app/src/test/java/com/hyzq/boss/ProjectDetailActivityUiTest.java
index bac5c67..8d2be64 100644
--- a/android/app/src/test/java/com/hyzq/boss/ProjectDetailActivityUiTest.java
+++ b/android/app/src/test/java/com/hyzq/boss/ProjectDetailActivityUiTest.java
@@ -12,6 +12,7 @@ import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.content.res.ColorStateList;
import android.graphics.drawable.GradientDrawable;
+import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -47,6 +48,49 @@ import java.util.function.BooleanSupplier;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 34)
public class ProjectDetailActivityUiTest {
+ @Test
+ public void chatSubpageTypographyUsesWechatCompactSizing() {
+ Intent intent = new Intent()
+ .putExtra(ProjectDetailActivity.EXTRA_PROJECT_ID, "project-1")
+ .putExtra(ProjectDetailActivity.EXTRA_PROJECT_NAME, "北区试产线回归");
+ TestProjectDetailActivity activity = Robolectric
+ .buildActivity(TestProjectDetailActivity.class, intent)
+ .setup()
+ .get();
+
+ LinearLayout topBar = activity.findViewById(R.id.screen_top_bar);
+ TextView title = activity.findViewById(R.id.screen_title);
+ TextView subtitle = activity.findViewById(R.id.screen_subtitle);
+ LinearLayout quickActions = activity.findViewById(R.id.project_chat_quick_actions);
+ ImageButton attachButton = activity.findViewById(R.id.project_chat_attach);
+ EditText input = activity.findViewById(R.id.project_chat_input);
+ Button sendButton = activity.findViewById(R.id.project_chat_send);
+ ReflectionHelpers.callInstanceMethod(activity, "renderQuickActions");
+
+ assertEquals("聊天子页面顶部栏左侧留白应和首页一致", BossUi.dp(activity, 16), topBar.getPaddingLeft());
+ assertFalse("聊天子页面标题不应保留 TextView 默认额外字体留白", title.getIncludeFontPadding());
+ assertFalse("聊天子页面副标题不应保留 TextView 默认额外字体留白", subtitle.getIncludeFontPadding());
+ assertEquals("聊天子页面标题不应换行撑高顶部栏", 1, title.getMaxLines());
+ assertEquals("聊天子页面副标题不应换行撑高顶部栏", 1, subtitle.getMaxLines());
+ assertEquals("聊天子页面副标题过长时应单行省略", TextUtils.TruncateAt.END, subtitle.getEllipsize());
+ assertEquals("聊天子页面标题应对标微信页面标题", 18f, title.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
+ assertEquals("聊天子页面副标题应对标微信辅助说明", 11f, subtitle.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
+
+ assertTrue("聊天子页面应渲染项目目标/版本记录按钮", quickActions.getChildCount() >= 2);
+ Button goalsButton = (Button) quickActions.getChildAt(0);
+ Button versionsButton = (Button) quickActions.getChildAt(1);
+ assertEquals("聊天子页面快捷按钮高度不应继续使用旧的大按钮", BossUi.dp(activity, 36), goalsButton.getLayoutParams().height);
+ assertEquals("聊天子页面快捷按钮文字应对标微信按钮字号", 13f, goalsButton.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
+ assertEquals("聊天子页面快捷按钮高度应统一", BossUi.dp(activity, 36), versionsButton.getLayoutParams().height);
+
+ assertEquals("聊天输入附件按钮不应继续使用 48dp 大图标", BossUi.dp(activity, 40), attachButton.getLayoutParams().width);
+ assertEquals("聊天输入附件按钮不应继续使用 48dp 大图标", BossUi.dp(activity, 40), attachButton.getLayoutParams().height);
+ assertTrue("聊天输入框最小高度不应继续撑大底部输入区", input.getMinHeight() <= BossUi.dp(activity, 40));
+ assertEquals("聊天输入框字号应和微信输入区一致", 14f, input.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
+ assertEquals("发送按钮高度应和输入框一致", BossUi.dp(activity, 40), sendButton.getLayoutParams().height);
+ assertEquals("发送按钮字号应对标微信按钮字号", 13f, sendButton.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
+ }
+
@Test
public void typingAtInComposerShowsAgentMentionSuggestions() {
Intent intent = new Intent()
@@ -486,8 +530,8 @@ public class ProjectDetailActivityUiTest {
assertTrue(attachView instanceof ImageButton);
ViewGroup.LayoutParams params = attachView.getLayoutParams();
- assertTrue(params.width >= BossUi.dp(activity, 46));
- assertTrue(params.height >= BossUi.dp(activity, 46));
+ assertEquals(BossUi.dp(activity, 40), params.width);
+ assertEquals(BossUi.dp(activity, 40), params.height);
}
@Test
@@ -517,8 +561,8 @@ public class ProjectDetailActivityUiTest {
assertTrue((params.gravity & Gravity.LEFT) == Gravity.LEFT || (params.gravity & Gravity.START) == Gravity.START);
assertEquals(BossUi.dp(activity, 12), params.leftMargin);
assertTrue(params.bottomMargin >= BossUi.dp(activity, 12));
- assertEquals(BossUi.dp(activity, 48), params.width);
- assertEquals(BossUi.dp(activity, 48), params.height);
+ assertEquals(BossUi.dp(activity, 44), params.width);
+ assertEquals(BossUi.dp(activity, 44), params.height);
int baselineScrollCount = activity.scrollChatToBottomCount;
shortcutView.performClick();