style: 优化操作日志详情页卡片布局与流转状态对齐

- 三张卡片改为标题区(40dp 顶圆角) + 贯穿分割线 + 内容区(底圆角) 三段式结构
- 流转状态进度条按 4 字 label 估算宽度,动态计算 ll_steps 左偏移,
  让第一个节点的 label 与运单信息/操作详情卡片内容对齐到 15dp 基准线
- stepWidth 加上限,避免步数较少时单格过宽导致首节点偏右

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 14:38:52 +08:00
parent 48ab9d6e2e
commit bdb8612081
2 changed files with 171 additions and 82 deletions

View File

@@ -2,10 +2,12 @@ package com.lukouguoji.aerologic.page.log.detail
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Paint
import android.os.Bundle import android.os.Bundle
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
@@ -69,13 +71,33 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
val colorBlue = 0xFF1C8CF5.toInt() val colorBlue = 0xFF1C8CF5.toInt()
val colorGray = 0xFFCCCCCC.toInt() val colorGray = 0xFFCCCCCC.toInt()
val colorGreen = 0xFF4CAF50.toInt()
val dotSize = dp(10) val dotSize = dp(10)
val lineHeight = dp(2) val lineHeight = dp(2)
val labelHPadding = dp(6)
val alignBase = dp(15)
// 计算每个节点宽度:屏幕宽度的 80% 均分给所有节点 // 按"四个汉字 label"估算节点 label 宽度(含左右各 6dp padding
val labelTextSizePx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 13f, resources?.displayMetrics
)
val fourCharTextWidth = Paint().apply { textSize = labelTextSizePx }
.measureText("测测测测").toInt()
val estimatedLabelWidth = fourCharTextWidth + labelHPadding * 2
// 计算每个节点宽度:屏幕宽度的 80% 均分给所有节点,并加上限避免步数少时单格过宽
val screenWidth = resources!!.displayMetrics.widthPixels val screenWidth = resources!!.displayMetrics.widthPixels
val stepWidth = (screenWidth * 0.8 / steps.size).toInt() val rawStepWidth = (screenWidth * 0.8 / steps.size).toInt()
val maxStepWidth = estimatedLabelWidth + dp(40)
val stepWidth = minOf(rawStepWidth, maxStepWidth)
// 让第一个 label居中在 stepWidth 内)的左边缘对齐到卡片内 15dp 基准线
// labelLeftInStep = (stepWidth - estimatedLabelWidth) / 2
// 所需 ll_steps leftMargin = alignBase - labelLeftInStep
val labelLeftInStep = (stepWidth - estimatedLabelWidth) / 2
(container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.leftMargin = alignBase - labelLeftInStep
container.layoutParams = it
}
// 找到最新节点在步骤列表中的索引 // 找到最新节点在步骤列表中的索引
val latestIndex = steps.indexOfFirst { it.code == latestCode } val latestIndex = steps.indexOfFirst { it.code == latestCode }
@@ -87,7 +109,7 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
val isFirst = i == 0 val isFirst = i == 0
val isLast = i == steps.size - 1 val isLast = i == steps.size - 1
// 每个步骤的根容器 // 每个步骤的根容器内部水平居中label 与圆点都在 stepWidth 中心)
val stepLayout = LinearLayout(this).apply { val stepLayout = LinearLayout(this).apply {
orientation = LinearLayout.VERTICAL orientation = LinearLayout.VERTICAL
gravity = Gravity.CENTER_HORIZONTAL gravity = Gravity.CENTER_HORIZONTAL
@@ -99,7 +121,7 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
text = step.name text = step.name
setTextSize(TypedValue.COMPLEX_UNIT_SP, 13f) setTextSize(TypedValue.COMPLEX_UNIT_SP, 13f)
gravity = Gravity.CENTER gravity = Gravity.CENTER
setPadding(dp(6), dp(2), dp(6), dp(2)) setPadding(labelHPadding, dp(2), labelHPadding, dp(2))
if (isLatest) { if (isLatest) {
setBackgroundResource(R.drawable.bg_step_current_badge) setBackgroundResource(R.drawable.bg_step_current_badge)
setTextColor(0xFFFFFFFF.toInt()) setTextColor(0xFFFFFFFF.toInt())
@@ -120,9 +142,8 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
).apply { topMargin = dp(8) } ).apply { topMargin = dp(8) }
} }
// 左半连线(从左边缘到中心) // 左半连线(从左边缘到圆点中心)
if (!isFirst) { if (!isFirst) {
// 如果当前节点索引 <= latestIndex左半线为蓝色否则为浅灰色
val leftLineColor = if (latestIndex >= 0 && i <= latestIndex) colorBlue else colorGray val leftLineColor = if (latestIndex >= 0 && i <= latestIndex) colorBlue else colorGray
val lineLeft = View(this).apply { val lineLeft = View(this).apply {
setBackgroundColor(leftLineColor) setBackgroundColor(leftLineColor)
@@ -138,9 +159,8 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
} }
} }
// 右半连线(从中心到右边缘) // 右半连线(从圆点中心到右边缘)
if (!isLast) { if (!isLast) {
// 如果当前节点索引 < latestIndex右半线为蓝色否则为浅灰色
val rightLineColor = if (latestIndex >= 0 && i < latestIndex) colorBlue else colorGray val rightLineColor = if (latestIndex >= 0 && i < latestIndex) colorBlue else colorGray
val lineRight = View(this).apply { val lineRight = View(this).apply {
setBackgroundColor(rightLineColor) setBackgroundColor(rightLineColor)
@@ -156,7 +176,7 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
} }
} }
// 圆点(叠加在连线之上) // 圆点(居中叠加在连线之上)
val dot = View(this).apply { val dot = View(this).apply {
setBackgroundResource( setBackgroundResource(
when { when {

View File

@@ -32,9 +32,15 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8" android:orientation="vertical">
android:orientation="vertical"
android:padding="15dp"> <!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -43,11 +49,26 @@
android:textColor="#333333" android:textColor="#333333"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout>
<!-- 分割线(贯穿卡片宽度) -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginHorizontal="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal"> android:orientation="horizontal">
<LinearLayout <LinearLayout
@@ -98,14 +119,22 @@
</LinearLayout> </LinearLayout>
</LinearLayout>
<!-- 流转状态 --> <!-- 流转状态 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_8" android:orientation="vertical">
android:orientation="vertical"
android:padding="15dp"> <!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -114,24 +143,47 @@
android:textColor="#333333" android:textColor="#333333"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/ll_steps" android:id="@+id/ll_steps"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginHorizontal="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal" /> android:orientation="horizontal" />
</LinearLayout> </LinearLayout>
</LinearLayout>
<!-- 操作详情 --> <!-- 操作详情 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_8" android:orientation="vertical">
android:orientation="vertical"
android:padding="15dp"> <!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -140,12 +192,27 @@
android:textColor="#333333" android:textColor="#333333"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_timeline" android:id="@+id/rv_timeline"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:nestedScrollingEnabled="false" android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
@@ -153,6 +220,8 @@
</LinearLayout> </LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </LinearLayout>