feat(inspection): 添加成品件接收检验功能模块

- 在OfflineCmdServiceHelper中增加Inspect页面关键词监听功能
- 实现InspectionActivity页面重构,添加拍照功能和界面交互
- 创建InspectionResultActivity用于展示检验结果和操作选项
- 新增InspectionMissingActivity和InspectionCompleteActivity页面
- 集成GlassMediaServiceHelper拍照功能和照片回调处理
- 添加SprayingPhotoManager照片管理功能
- 更新界面布局文件activity_inspection.xml优化UI结构
- 在AndroidManifest.xml中注册新增的检验相关Activity
- 实现检验结果的随机生成和状态显示逻辑
这个提交包含在:
徐勤民 2026-04-15 15:59:36 +08:00
父节点 699221bb55
当前提交 d7b14b2bce
共有 14 个文件被更改,包括 873 次插入64 次删除

二进制文件未显示。

二进制文件未显示。

查看文件

@ -78,6 +78,15 @@
<activity
android:name=".ui.InspectionActivity"
android:exported="false" />
<activity
android:name=".ui.InspectionResultActivity"
android:exported="false" />
<activity
android:name=".ui.InspectionMissingActivity"
android:exported="false" />
<activity
android:name=".ui.InspectionCompleteActivity"
android:exported="false" />
<activity
android:name=".ui.SprayingActivity"
android:exported="false" />

查看文件

@ -277,4 +277,48 @@ object OfflineCmdServiceHelper {
))
}
// ---- Inspection 页面关键词 ----
fun addListenerInspectionResult(){
registerBeans(listOf(
OfflineCmdBean("重拍照", "chong pai zhao"),
OfflineCmdBean("结束任务", "jie shu ren wu"),
OfflineCmdBean("继续任务", "ji xu ren wu")
))
}
fun removeListenerInspectionResult(){
removeBeans(listOf(
OfflineCmdBean("重拍照", "chong pai zhao"),
OfflineCmdBean("结束任务", "jie shu ren wu"),
OfflineCmdBean("继续任务", "ji xu ren wu")
))
}
fun addListenerInspectionMissing(){
registerBeans(listOf(
OfflineCmdBean("补充单证", "bu chong dan zheng"),
OfflineCmdBean("继续提交", "ji xu ti jiao")
))
}
fun removeListenerInspectionMissing(){
removeBeans(listOf(
OfflineCmdBean("补充单证", "bu chong dan zheng"),
OfflineCmdBean("继续提交", "ji xu ti jiao")
))
}
fun addListenerInspectionComplete(){
registerBeans(listOf(
OfflineCmdBean("完成任务", "wan cheng ren wu")
))
}
fun removeListenerInspectionComplete(){
removeBeans(listOf(
OfflineCmdBean("完成任务", "wan cheng ren wu")
))
}
}

查看文件

@ -1,73 +1,102 @@
package com.nova.brain.glass.ui
import androidx.recyclerview.widget.RecyclerView
import android.content.Intent
import android.os.Environment
import android.view.WindowManager
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityInspectionBinding
import com.nova.brain.glass.helper.GlassMediaServiceHelper
import com.nova.brain.glass.helper.OfflineCmdListener
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
import com.nova.brain.glass.model.ItemItem
import com.nova.brain.glass.viewmodel.ItemListVM
import com.xuqm.base.adapter.BasePagedAdapter
import com.xuqm.base.adapter.CommonPagedAdapter
import com.xuqm.base.adapter.ViewHolder
import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
import com.nova.brain.glass.helper.SprayingPhotoManager
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
import com.rokid.security.system.server.media.callback.PhotoFileCallback
import com.xuqm.base.common.LogHelper
import com.xuqm.base.extensions.showMessage
import com.xuqm.base.ui.BaseActivity
import java.io.File
import java.util.UUID
import kotlin.jvm.java
class InspectionActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, ActivityInspectionBinding>() {
override fun getLayoutId(): Int =R.layout.activity_inspection
class InspectionActivity : BaseActivity<ActivityInspectionBinding>() {
override fun getLayoutId(): Int = R.layout.activity_inspection
override fun fullscreen(): Boolean = true
override fun getRecyclerOrientation(): Int = RecyclerView.HORIZONTAL
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
runOnUiThread {
when( cmd){
"退出","返回","退回"->{
finish()
}
"驳回","拒绝","不同意"->{
finish()
}
"同意","通过"->{
finish()
}
when (cmd) {
"退出", "返回", "退回" -> finish()
"开始", "开始任务", "拍照" -> startCapture()
}
}
}
}
override fun initData() {
super.initData()
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
SprayingPhotoManager.clear()
binding.btnCamera.setOnClickListener { startCapture() }
binding.btnPrev.setOnClickListener { /* 切换上一任务(待实现) */ }
binding.btnNext.setOnClickListener { /* 切换下一任务(待实现) */ }
}
private fun startCapture() {
binding.hint.text = "拍照中,请稍后..."
SprayingPhotoManager.clear()
takePhoto()
}
private fun takePhoto() {
val fileName = "inspection_${System.currentTimeMillis()}.png"
val file = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
fileName
)
GlassMediaServiceHelper.takePhoto(PhotoResolution.RESOLUTION_480P, file.absolutePath)
}
private val photoCallbackId = UUID.randomUUID().toString()
private val mPhotoFileCallback = object : PhotoFileCallback.Stub() {
override fun onTakePhoto(path: String) {
LogHelper.d("onTakePhoto: $path")
}
override fun getCallbackId(): String = photoCallbackId
override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
if (path == null) {
runOnUiThread {
binding.hint.text = "单击或语音输入\u201C开始\u201D,进入下一步\n滑动切换上/下一个任务"
}
"相机异常".showMessage()
return
}
SprayingPhotoManager.addPhoto(path)
runOnUiThread {
startActivity(Intent(this@InspectionActivity, InspectionResultActivity::class.java).apply {
putExtra(InspectionResultActivity.EXTRA_PHOTO_PATH, path)
})
}
}
}
override fun onResume() {
super.onResume()
OfflineCmdServiceHelper.addListenerInspection()
GlassMediaServiceHelper.addPhotoCallback(mPhotoFileCallback)
OfflineCmdServiceHelper.addOnLineListener(listener)
}
override fun onPause() {
super.onPause()
OfflineCmdServiceHelper.removeListenerInspection()
GlassMediaServiceHelper.removePhotoCallback(mPhotoFileCallback)
OfflineCmdServiceHelper.removeOnLineListener(listener)
}
override fun onDestroy() {
super.onDestroy()
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_item) {
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
holder
.setText(R.id.text, item.text)
.setClickListener(R.id.text) {
when (item.text) {
"同意" -> finish()
"驳回" -> finish()
}
}
}
}
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
}

查看文件

@ -0,0 +1,53 @@
package com.nova.brain.glass.ui
import android.content.Intent
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityInspectionCompleteBinding
import com.nova.brain.glass.helper.OfflineCmdListener
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
import com.xuqm.base.ui.BaseActivity
class InspectionCompleteActivity : BaseActivity<ActivityInspectionCompleteBinding>() {
override fun getLayoutId(): Int = R.layout.activity_inspection_complete
override fun fullscreen(): Boolean = true
companion object {
const val EXTRA_PHOTO_COUNT = "extra_photo_count"
}
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
runOnUiThread {
when (cmd) {
"退出", "返回", "退回", "完成任务" -> finishTask()
}
}
}
}
override fun initData() {
super.initData()
val count = intent.getIntExtra(EXTRA_PHOTO_COUNT, 0)
binding.subtitle.text = "本次成功提交并归档${count}张单证!"
binding.btnFinish.setOnClickListener { finishTask() }
}
private fun finishTask() {
startActivity(Intent(this, TaskListActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
})
finish()
}
override fun onResume() {
super.onResume()
OfflineCmdServiceHelper.addListenerInspectionComplete()
OfflineCmdServiceHelper.addOnLineListener(listener)
}
override fun onPause() {
super.onPause()
OfflineCmdServiceHelper.removeListenerInspectionComplete()
OfflineCmdServiceHelper.removeOnLineListener(listener)
}
}

查看文件

@ -0,0 +1,77 @@
package com.nova.brain.glass.ui
import android.app.Activity
import android.content.Intent
import androidx.recyclerview.widget.RecyclerView
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityInspectionMissingBinding
import com.nova.brain.glass.helper.OfflineCmdListener
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
import com.nova.brain.glass.model.ItemItem
import com.nova.brain.glass.viewmodel.InspectionMissingVM
import com.xuqm.base.adapter.BasePagedAdapter
import com.xuqm.base.adapter.CommonPagedAdapter
import com.xuqm.base.adapter.ViewHolder
import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
class InspectionMissingActivity :
BaseListFormLayoutNormalActivity<ItemItem, InspectionMissingVM, ActivityInspectionMissingBinding>() {
override fun getLayoutId(): Int = R.layout.activity_inspection_missing
override fun fullscreen(): Boolean = true
override fun getRecyclerOrientation(): Int = RecyclerView.VERTICAL
companion object {
const val EXTRA_ACTION = "extra_action"
const val ACTION_SUPPLEMENT = "supplement"
const val ACTION_SUBMIT = "submit"
}
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
runOnUiThread {
when (cmd) {
"退出", "返回", "退回" -> finish()
"补充单证" -> supplement()
"继续提交" -> submit()
}
}
}
}
private fun supplement() {
setResult(Activity.RESULT_OK, Intent().putExtra(EXTRA_ACTION, ACTION_SUPPLEMENT))
finish()
}
private fun submit() {
setResult(Activity.RESULT_OK, Intent().putExtra(EXTRA_ACTION, ACTION_SUBMIT))
finish()
}
override fun onResume() {
super.onResume()
OfflineCmdServiceHelper.addListenerInspectionMissing()
OfflineCmdServiceHelper.addOnLineListener(listener)
}
override fun onPause() {
super.onPause()
OfflineCmdServiceHelper.removeListenerInspectionMissing()
OfflineCmdServiceHelper.removeOnLineListener(listener)
}
private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_manual_result_action) {
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
holder.setText(R.id.text, item.text)
.setClickListener(R.id.actionRoot) {
when (item.text) {
"补充单证" -> supplement()
"继续提交" -> submit()
}
}
}
}
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
}

查看文件

@ -0,0 +1,224 @@
package com.nova.brain.glass.ui
import android.app.Activity
import android.content.Intent
import android.os.CountDownTimer
import android.os.Environment
import android.view.WindowManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.doOnLayout
import androidx.recyclerview.widget.RecyclerView
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityInspectionResultBinding
import com.nova.brain.glass.helper.BitmapDecodeHelper
import com.nova.brain.glass.helper.GlassMediaServiceHelper
import com.nova.brain.glass.helper.OfflineCmdListener
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
import com.nova.brain.glass.helper.SprayingPhotoManager
import com.nova.brain.glass.model.ItemItem
import com.nova.brain.glass.viewmodel.InspectionResultVM
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
import com.rokid.security.system.server.media.callback.PhotoFileCallback
import com.xuqm.base.adapter.BasePagedAdapter
import com.xuqm.base.adapter.CommonPagedAdapter
import com.xuqm.base.adapter.ViewHolder
import com.xuqm.base.common.LogHelper
import com.xuqm.base.extensions.showMessage
import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
import java.io.File
import java.util.UUID
import java.util.concurrent.Executors
import kotlin.random.Random
class InspectionResultActivity :
BaseListFormLayoutNormalActivity<ItemItem, InspectionResultVM, ActivityInspectionResultBinding>() {
override fun getLayoutId(): Int = R.layout.activity_inspection_result
override fun fullscreen(): Boolean = true
override fun getRecyclerOrientation(): Int = RecyclerView.HORIZONTAL
private val imageDecodeExecutor = Executors.newSingleThreadExecutor()
private var status = true // true=合格, false=不合格
private var resultCountdown: CountDownTimer? = null
companion object {
const val EXTRA_PHOTO_PATH = "extra_photo_path"
}
private val missingLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
when (result.data?.getStringExtra(InspectionMissingActivity.EXTRA_ACTION)) {
InspectionMissingActivity.ACTION_SUPPLEMENT -> {
// 补充单证:重新拍照
binding.tvTaskHeader.text = "拍照中,请稍后..."
takePhoto()
}
InspectionMissingActivity.ACTION_SUBMIT -> {
goComplete()
}
}
}
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
runOnUiThread {
when (cmd) {
"退出", "返回", "退回" -> finish()
"重拍照" -> retake()
"继续任务" -> continueTask()
"结束任务" -> endTask()
}
}
}
}
override fun initData() {
super.initData()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
val path = intent.getStringExtra(EXTRA_PHOTO_PATH)
if (path != null) {
showPhoto(path)
}
// 拍完照等待5秒后显示结果
startResultCountdown()
}
/** 等待 5 秒后随机显示合格/不合格结果 */
private fun startResultCountdown(seconds: Long = 5) {
binding.tvTaskHeader.text = "识别中,请稍后..."
resultCountdown?.cancel()
resultCountdown = object : CountDownTimer(seconds * 1000, 1000) {
override fun onTick(millisUntilFinished: Long) {}
override fun onFinish() {
status = Random.nextBoolean()
runOnUiThread { updateResultDisplay() }
}
}.start()
}
private fun updateResultDisplay() {
binding.tvTaskHeader.text = if (status) "检验结果:合格!" else "检验结果:不合格!"
binding.status.setImageResource(if (status) R.mipmap.ocr_true else R.mipmap.ocr_false)
}
private fun retake() {
binding.tvTaskHeader.text = "重新拍照中,请稍后..."
takePhoto()
}
private fun continueTask() {
binding.tvTaskHeader.text = "拍照中,请稍后..."
takePhoto()
}
private fun endTask() {
// 随机进入单证缺失或单证齐全
if (Random.nextBoolean()) {
missingLauncher.launch(Intent(this, InspectionMissingActivity::class.java))
} else {
goComplete()
}
}
private fun goComplete() {
val photoCount = SprayingPhotoManager.getPhotoCount()
SprayingPhotoManager.clear()
startActivity(Intent(this, InspectionCompleteActivity::class.java).apply {
putExtra(InspectionCompleteActivity.EXTRA_PHOTO_COUNT, photoCount)
})
finish()
}
// ---- 拍照 ----
private fun takePhoto() {
val fileName = "inspection_${System.currentTimeMillis()}.png"
val file = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
fileName
)
GlassMediaServiceHelper.takePhoto(PhotoResolution.RESOLUTION_480P, file.absolutePath)
}
private val photoCallbackId = UUID.randomUUID().toString()
private val mPhotoFileCallback = object : PhotoFileCallback.Stub() {
override fun onTakePhoto(path: String) {
LogHelper.d("onTakePhoto: $path")
}
override fun getCallbackId(): String = photoCallbackId
override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
if (path == null) {
runOnUiThread {
binding.tvTaskHeader.text = "相机异常,请重试"
}
"相机异常".showMessage()
return
}
SprayingPhotoManager.addPhoto(path)
runOnUiThread {
showPhoto(path)
// 重拍/继续任务等待3秒后刷新结果
startResultCountdown(3)
}
}
}
private fun showPhoto(path: String) {
binding.iv.doOnLayout {
val w = it.width.coerceAtLeast(1)
val h = it.height.coerceAtLeast(1)
imageDecodeExecutor.execute {
val bitmap = BitmapDecodeHelper.decodeSampledBitmap(path, w, h)
runOnUiThread {
if (!isFinishing && !isDestroyed) {
binding.iv.setImageBitmap(bitmap)
}
}
}
}
}
// ---- 生命周期 ----
override fun onResume() {
super.onResume()
OfflineCmdServiceHelper.addListenerInspectionResult()
OfflineCmdServiceHelper.addOnLineListener(listener)
GlassMediaServiceHelper.addPhotoCallback(mPhotoFileCallback)
}
override fun onPause() {
super.onPause()
resultCountdown?.cancel()
OfflineCmdServiceHelper.removeListenerInspectionResult()
OfflineCmdServiceHelper.removeOnLineListener(listener)
GlassMediaServiceHelper.removePhotoCallback(mPhotoFileCallback)
}
override fun onDestroy() {
super.onDestroy()
binding.iv.setImageDrawable(null)
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
// ---- Adapter ----
private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_manual_result_action) {
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
holder.setText(R.id.text, item.text)
.setClickListener(R.id.actionRoot) {
when (item.text) {
"重拍照" -> retake()
"结束任务" -> endTask()
"继续任务" -> continueTask()
}
}
}
}
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
}

查看文件

@ -0,0 +1,14 @@
package com.nova.brain.glass.viewmodel
import com.nova.brain.glass.model.ItemItem
import com.xuqm.base.viewmodel.BaseListViewModel
import com.xuqm.base.viewmodel.callback.Response
class InspectionMissingVM : BaseListViewModel<ItemItem>() {
override fun loadData(page: Int, onResponse: Response<ItemItem>) {
onResponse.onResponse(arrayListOf<ItemItem>().apply {
add(ItemItem("补充单证"))
add(ItemItem("继续提交"))
})
}
}

查看文件

@ -0,0 +1,15 @@
package com.nova.brain.glass.viewmodel
import com.nova.brain.glass.model.ItemItem
import com.xuqm.base.viewmodel.BaseListViewModel
import com.xuqm.base.viewmodel.callback.Response
class InspectionResultVM : BaseListViewModel<ItemItem>() {
override fun loadData(page: Int, onResponse: Response<ItemItem>) {
onResponse.onResponse(arrayListOf<ItemItem>().apply {
add(ItemItem("重拍照"))
add(ItemItem("结束任务"))
add(ItemItem("继续任务"))
})
}
}

查看文件

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main"
@ -12,9 +11,10 @@
android:id="@+id/tvTaskHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="67dp"
android:layout_marginTop="16dp"
android:background="@drawable/bg_item"
android:text="装配工序喷涂识别您还有10项任务未完成"
android:gravity="center"
android:text="成品件接收检验您还有10项任务未完成"
android:textColor="#ff40FF5E"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
@ -22,8 +22,8 @@
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/bg_task_title_selected"
@ -39,7 +39,7 @@
android:layout_gravity="center"
android:layout_marginVertical="3dp"
android:gravity="center"
android:text="任务1:管线编号与机身喷码核对"
android:text="任务1"
android:textColor="#ff40FF5E"
android:textSize="18sp"
android:textStyle="bold" />
@ -57,49 +57,98 @@
android:layout_marginTop="4dp"
android:text="任务编号20293989-001"
android:textColor="#ff40FF5E"
android:textSize="14sp"/>
android:textSize="14sp" />
<TextView
android:id="@+id/content2"
android:layout_width="match_parent"
android:layout_marginStart="15dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="4dp"
android:text="制造供应商:中航成飞民用飞机有限责任公司"
android:textColor="#ff40FF5E"
android:textSize="14sp"/>
android:textSize="14sp" />
<TextView
android:id="@+id/content3"
android:layout_width="match_parent"
android:layout_marginStart="15dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginVertical="4dp"
android:text="任务创建时间2026-03-09 16:00:00"
android:textColor="#ff40FF5E"
android:textSize="14sp"/>
android:textSize="14sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/baseRecyclerView"
<!-- 拍照区:左箭头 | 相机按钮 | 右箭头 -->
<LinearLayout
android:id="@+id/cameraRow"
android:layout_width="0dp"
android:layout_height="88dp"
android:layout_marginTop="12dp"
android:overScrollMode="never"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/content" />
app:layout_constraintTop_toBottomOf="@+id/content">
<TextView
android:id="@+id/btnPrev"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="◀"
android:textColor="#ff40FF5E"
android:textSize="32sp" />
<LinearLayout
android:id="@+id/btnCamera"
android:layout_width="88dp"
android:layout_height="88dp"
android:background="@drawable/bg_photo"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="24dp"
android:src="@mipmap/paizhao" />
<TextView
android:id="@+id/btnCameraText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="开始任务"
android:textColor="#ff40FF5E"
android:textSize="14sp" />
</LinearLayout>
<TextView
android:id="@+id/btnNext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="▶"
android:textColor="#ff40FF5E"
android:textSize="32sp" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_marginStart="15dp"
android:id="@+id/hint"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView"
android:layout_marginVertical="4dp"
android:layout_marginTop="12dp"
android:gravity="center"
android:text="单击或语音输入“开始”,进入下一步"
android:text='单击或语音输入"开始",进入下一步\n滑动切换上/下一个任务'
android:textColor="#ff40FF5E"
android:textSize="14sp"/>
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cameraRow" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

查看文件

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_color_black">
<ImageView
android:id="@+id/icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="60dp"
android:src="@mipmap/ocr_true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="本次任务:单证齐全"
android:textColor="#ff40FF5E"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/icon" />
<TextView
android:id="@+id/subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="本次成功提交并归档3张单证"
android:textColor="#ff40FF5E"
android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
<FrameLayout
android:id="@+id/btnFinish"
android:layout_width="230dp"
android:layout_height="64dp"
android:layout_marginTop="40dp"
android:background="@drawable/bg_item"
android:foreground="?attr/selectableItemBackground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/subtitle">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="完成任务"
android:textColor="#ff40FF5E"
android:textSize="20sp" />
</FrameLayout>
<TextView
android:id="@+id/hint"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:text='单击或语音输入"完成任务",结束本次任务'
android:textColor="#ff40FF5E"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnFinish" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

查看文件

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_color_black">
<ImageView
android:id="@+id/icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="32dp"
android:src="@mipmap/ocr_false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:gravity="center"
android:text="本次任务:单证缺失"
android:textColor="#ff40FF5E"
android:textSize="22sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/icon" />
<TextView
android:id="@+id/subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="缺失2张单证,建议补充后提交"
android:textColor="#ff40FF5E"
android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
<TextView
android:id="@+id/missingList"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="12dp"
android:lineSpacingExtra="6dp"
android:text="·XX件号XX序列号缺少「合格证」\n·XX件号XX序列号缺少「装箱单」"
android:textColor="#ff40FF5E"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/subtitle" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/baseRecyclerView"
android:layout_width="230dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:overScrollMode="never"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/missingList" />
<TextView
android:id="@+id/hint"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:lineSpacingExtra="6dp"
android:text='单击或语音输入"补充单证",继续拍摄单证\n单击或语音输入"继续提交",提交并结束该任务'
android:textColor="#ff40FF5E"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

查看文件

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_color_black">
<TextView
android:id="@+id/tvTaskHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/bg_item"
android:gravity="center"
android:text="检验结果:合格!"
android:textColor="#ff40FF5E"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- 结果卡片 -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cardResult"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/bg_task_title_selected"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTaskHeader">
<ImageView
android:id="@+id/iv"
android:layout_width="100dp"
android:layout_height="130dp"
android:background="@drawable/bg_task_title_selected"
android:padding="2dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/status"
app:layout_constraintStart_toEndOf="@+id/iv"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/value1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="单证类型:合格证"
android:textColor="#ff40FF5E"
android:textSize="14sp" />
<TextView
android:id="@+id/value2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="件号20293989-001"
android:textColor="#ff40FF5E"
android:textSize="14sp" />
<TextView
android:id="@+id/value3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="序列号20293989-001"
android:textColor="#ff40FF5E"
android:textSize="14sp" />
<TextView
android:id="@+id/value4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="供应商:中航成飞民用飞机有限责任公司"
android:textColor="#ff40FF5E"
android:textSize="14sp" />
</LinearLayout>
<!-- 合格/不合格 角标 -->
<ImageView
android:id="@+id/status"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@mipmap/ocr_true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/baseRecyclerView"
android:layout_width="0dp"
android:layout_height="88dp"
android:layout_marginTop="16dp"
android:overScrollMode="never"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardResult" />
<TextView
android:id="@+id/hint"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:lineSpacingExtra="4dp"
android:text='单击或语音输入"重拍照",重新拍摄当前证件\n单击或语音输入"继续任务",继续拍摄下一张证件\n单击或语音输入"结束任务",结束全部拍摄并提交'
android:textColor="#ff40FF5E"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>