style: 语音按钮视觉优化

- 背景改为橙色半透明+边框,和指引块风格统一
- 宽度 match_parent,内含声波图标+语音描述+时长
- 播放中切换背景高亮+停止图标,停止后恢复
- 新增 bg_btn_voice_playing.xml 播放状态背景

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-05-06 20:52:09 +09:30
parent 2e7edc7e09
commit d5cdcc8186
4 changed files with 58 additions and 23 deletions

View File

@@ -396,7 +396,7 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
/** /**
* 显示语音播放按钮(用户上报任务 taskType=3/4 可能有语音附件) * 显示语音播放按钮(用户上报任务 taskType=3/4 可能有语音附件)
* 点击播放/暂停语音 * 点击切换播放/停止,图标和背景跟随状态变化
*/ */
private fun showVoice(detail: TaskDetail) { private fun showVoice(detail: TaskDetail) {
if (!detail.hasVoice) return if (!detail.hasVoice) return
@@ -405,8 +405,10 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
if (voiceItem.url.isEmpty()) return if (voiceItem.url.isEmpty()) return
// 显示按钮和时长 // 显示按钮和时长
binding.tvVoiceDuration.text = "${voiceItem.voiceLength}\"" binding.tvVoiceDuration.text = "${voiceItem.voiceLength}\u2033"
binding.btnVoice.visibility = View.VISIBLE binding.btnVoice.visibility = View.VISIBLE
// 初始化为未播放状态
updateVoiceUI(false)
// 点击播放/停止 // 点击播放/停止
binding.btnVoice.setOnClickListener { binding.btnVoice.setOnClickListener {
@@ -414,14 +416,24 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
} }
} }
/** 更新语音按钮的图标和背景 */
private fun updateVoiceUI(playing: Boolean) {
if (playing) {
binding.tvVoiceIcon.text = "\u23F9" // ⏹ 停止图标
binding.btnVoice.setBackgroundResource(R.drawable.bg_btn_voice_playing)
} else {
binding.tvVoiceIcon.text = "\uD83D\uDD0A" // 🔊 喇叭图标
binding.btnVoice.setBackgroundResource(R.drawable.bg_btn_voice)
}
}
/** 播放/停止语音 */ /** 播放/停止语音 */
private fun toggleVoice(url: String) { private fun toggleVoice(url: String) {
if (mediaPlayer?.isPlaying == true) { if (mediaPlayer?.isPlaying == true) {
// 正在播放 → 停止
stopVoice() stopVoice()
} else { } else {
// 没有播放 → 开始
stopVoice() // 清理上一个 stopVoice() // 清理上一个
updateVoiceUI(true)
mediaPlayer = MediaPlayer().apply { mediaPlayer = MediaPlayer().apply {
setDataSource(url) setDataSource(url)
setOnPreparedListener { start() } setOnPreparedListener { start() }
@@ -436,13 +448,17 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
} }
} }
/** 停止并释放 MediaPlayer */ /** 停止并释放 MediaPlayer,恢复按钮状态 */
private fun stopVoice() { private fun stopVoice() {
mediaPlayer?.let { mediaPlayer?.let {
if (it.isPlaying) it.stop() if (it.isPlaying) it.stop()
it.release() it.release()
} }
mediaPlayer = null mediaPlayer = null
// 恢复未播放状态(页面销毁时 binding 可能已失效)
if (view != null) {
updateVoiceUI(false)
}
} }
/** /**

View File

@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- 语音播放按钮:橙色圆角(兼容 API 27+ --> <!-- 语音播放按钮:橙色半透明,和指引块风格统一 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"> <item android:state_pressed="true">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="#FFCC8820" /> <solid android:color="#40FFB340" />
<corners android:radius="24dp" /> <corners android:radius="27dp" />
<stroke android:width="1dp" android:color="#80FFB340" />
</shape> </shape>
</item> </item>
<item> <item>
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="#FFEB9A26" /> <solid android:color="#30FFB340" />
<corners android:radius="24dp" /> <corners android:radius="27dp" />
<stroke android:width="1dp" android:color="#50FFB340" />
</shape> </shape>
</item> </item>
</selector> </selector>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 语音按钮播放中状态:橙色更亮,表示活跃 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#60FFB340" />
<corners android:radius="27dp" />
<stroke android:width="2dp" android:color="#FFFFB340" />
</shape>

View File

@@ -134,35 +134,44 @@
android:layout_marginBottom="11dp" android:layout_marginBottom="11dp"
android:visibility="gone" /> android:visibility="gone" />
<!-- 语音播放按钮(用户上报任务附带语音) --> <!-- 语音播放按钮(用户上报任务附带语音描述 -->
<LinearLayout <LinearLayout
android:id="@+id/btnVoice" android:id="@+id/btnVoice"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="56dp"
android:background="@drawable/bg_btn_voice" android:background="@drawable/bg_btn_voice"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingStart="16dp" android:paddingStart="19dp"
android:paddingEnd="24dp" android:paddingEnd="19dp"
android:layout_marginBottom="11dp" android:layout_marginBottom="11dp"
android:visibility="gone"> android:visibility="gone">
<!-- 播放图标 --> <!-- 声波图标(播放中切换为暂停) -->
<TextView <TextView
android:id="@+id/tvVoiceIcon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="" android:text="🔊"
android:textColor="@color/text_primary" android:textSize="26sp" />
android:textSize="24sp" />
<!-- 语音标签 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="语音描述"
android:textColor="@color/warning"
android:textSize="24sp"
android:textStyle="bold"
android:layout_marginStart="11dp" />
<!-- 语音时长 --> <!-- 语音时长 -->
<TextView <TextView
android:id="@+id/tvVoiceDuration" android:id="@+id/tvVoiceDuration"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/text_primary" android:textColor="@color/text_secondary"
android:textSize="24sp" android:textSize="22sp" />
android:textStyle="bold"
android:layout_marginStart="8dp" />
</LinearLayout> </LinearLayout>