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.Intent
import android.graphics.Paint
import android.os.Bundle
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
@@ -69,13 +71,33 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
val colorBlue = 0xFF1C8CF5.toInt()
val colorGray = 0xFFCCCCCC.toInt()
val colorGreen = 0xFF4CAF50.toInt()
val dotSize = dp(10)
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 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 }
@@ -87,7 +109,7 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
val isFirst = i == 0
val isLast = i == steps.size - 1
// 每个步骤的根容器
// 每个步骤的根容器内部水平居中label 与圆点都在 stepWidth 中心)
val stepLayout = LinearLayout(this).apply {
orientation = LinearLayout.VERTICAL
gravity = Gravity.CENTER_HORIZONTAL
@@ -99,7 +121,7 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
text = step.name
setTextSize(TypedValue.COMPLEX_UNIT_SP, 13f)
gravity = Gravity.CENTER
setPadding(dp(6), dp(2), dp(6), dp(2))
setPadding(labelHPadding, dp(2), labelHPadding, dp(2))
if (isLatest) {
setBackgroundResource(R.drawable.bg_step_current_badge)
setTextColor(0xFFFFFFFF.toInt())
@@ -120,9 +142,8 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
).apply { topMargin = dp(8) }
}
// 左半连线(从左边缘到中心)
// 左半连线(从左边缘到圆点中心)
if (!isFirst) {
// 如果当前节点索引 <= latestIndex左半线为蓝色否则为浅灰色
val leftLineColor = if (latestIndex >= 0 && i <= latestIndex) colorBlue else colorGray
val lineLeft = View(this).apply {
setBackgroundColor(leftLineColor)
@@ -138,9 +159,8 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
}
}
// 右半连线(从中心到右边缘)
// 右半连线(从圆点中心到右边缘)
if (!isLast) {
// 如果当前节点索引 < latestIndex右半线为蓝色否则为浅灰色
val rightLineColor = if (latestIndex >= 0 && i < latestIndex) colorBlue else colorGray
val lineRight = View(this).apply {
setBackgroundColor(rightLineColor)
@@ -156,7 +176,7 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
}
}
// 圆点(叠加在连线之上)
// 圆点(居中叠加在连线之上)
val dot = View(this).apply {
setBackgroundResource(
when {

View File

@@ -32,65 +32,88 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="15dp">
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单信息"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 标题区 -->
<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
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单信息"
android:textColor="#333333"
android:textSize="16sp"
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:layout_marginTop="12dp"
android:orientation="horizontal">
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="运单号:"
android:textColor="#666666"
android:textSize="14sp" />
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单号:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillNo}"
android:textColor="#333333"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillNo}"
android:textColor="#333333"
android:textSize="14sp" />
android:layout_weight="1"
android:orientation="horizontal">
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:"
android:textColor="#666666"
android:textSize="14sp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillType}"
android:textColor="#333333"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillType}"
android:textColor="#333333"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
@@ -103,24 +126,47 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="流转状态"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
android:orientation="vertical">
<!-- 标题区 -->
<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
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="流转状态"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:id="@+id/ll_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal" />
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_steps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal" />
</LinearLayout>
</LinearLayout>
@@ -129,25 +175,48 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="15dp">
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="操作详情"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 标题区 -->
<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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_timeline"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="操作详情"
android:textColor="#333333"
android:textSize="16sp"
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:layout_marginTop="12dp"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_timeline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>