Browse Source

refactor(修改):
- 锁定站开关样式显示完成

周文健 5 months ago
parent
commit
43d1f52a35

+ 2 - 0
app/src/main/java/com/grkj/iscs/util/BitmapUtil.kt

@@ -8,6 +8,8 @@ import android.graphics.ImageFormat
 import android.graphics.Rect
 import android.graphics.YuvImage
 import android.os.Environment
+import androidx.annotation.DrawableRes
+import androidx.core.content.ContextCompat
 import com.bumptech.glide.Glide
 import com.bumptech.glide.load.DataSource
 import com.bumptech.glide.load.engine.GlideException

+ 82 - 50
app/src/main/java/com/grkj/iscs/view/fragment/StepFragment.kt

@@ -48,6 +48,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
     private var mTicketDetailData: TicketDetailRespVO? = null
     private lateinit var observer: Observer<MsgEvent>
     private var mCanHandle: Boolean? = null // 是否可以操作,创建人、上锁人至少符合一个才可操作
+    private var mapRatio: Float = 1f
 
     override val viewBinding: FragmentStepBinding
         get() = FragmentStepBinding.inflate(layoutInflater)
@@ -72,10 +73,8 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                             .setCardBackgroundColor(requireContext().getColor(R.color.item_rv_step_bg_done))
                     } else {
                         holder.getView<MaterialCardView>(R.id.cv_step).setCardBackgroundColor(
-                            if (mStep + 1 == step.index)
-                                requireContext().getColor(R.color.item_rv_step_bg_doing)
-                            else
-                                requireContext().getColor(R.color.common_bg_white_10)
+                            if (mStep + 1 == step.index) requireContext().getColor(R.color.item_rv_step_bg_doing)
+                            else requireContext().getColor(R.color.common_bg_white_10)
                         )
                     }
 
@@ -89,8 +88,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                     holder.getView<ImageView>(R.id.iv_status)
                         .setImageResource(if (step.stepDetail?.stepStatus == "1") R.mipmap.step_executed else R.mipmap.step_not_executed)
                     holder.setText(
-                        R.id.tv_status,
-                        if (step.stepDetail?.stepStatus == "1") {
+                        R.id.tv_status, if (step.stepDetail?.stepStatus == "1") {
                             if (step.index == 3) getString(R.string.allocated) else getString(R.string.executed)
                         } else {
                             if (step.index == 3) getString(R.string.not_allocated) else getString(R.string.not_executed)
@@ -145,8 +143,11 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
             if (mStep >= 4) {
                 changePage(
                     PageChangeBO(
-                        2, mChangePage?.workstationId, mChangePage?.ticketId,
-                        mChangePage?.machineryId, mChangePage?.machineryName
+                        2,
+                        mChangePage?.workstationId,
+                        mChangePage?.ticketId,
+                        mChangePage?.machineryId,
+                        mChangePage?.machineryName
                     )
                 )
             }
@@ -183,6 +184,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                     }
                 })
                 mBinding?.mapview?.addLayer(stationLayer)
+                stationLayer?.setRatio(mapRatio)
                 mBinding?.mapview?.refresh()
             }
 
@@ -237,8 +239,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
         }
 
         presenter?.getMachineryDetail(
-            pageChangeBO.machineryId!!,
-            {
+            pageChangeBO.machineryId!!, {
                 mMachineryDetail = it
                 Glide.with(this).load(it?.machineryImg).into(mBinding?.ivMachinery!!)
             }) { itList ->
@@ -250,43 +251,73 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
             if (mLotoList.isNotEmpty()) {
                 mLotoList[0].mapId?.let { itId ->
                     presenter?.getMapInfo(itId) { itMapInfo ->
-                        itMapInfo?.imageUrl ?: return@getMapInfo
-                        BitmapUtil.loadBitmapFromUrl(requireContext(), itMapInfo.imageUrl) {
-                            if (it == null) {
+                        // 如果没有图 URL,直接返回
+                        val imageUrl = itMapInfo?.imageUrl ?: return@getMapInfo
+
+                        BitmapUtil.loadBitmapFromUrl(requireContext(), imageUrl) { mapBmp ->
+                            if (mapBmp == null) {
                                 LogUtil.e("Map pic is null")
                                 return@loadBitmapFromUrl
                             }
-                            mMapPicWidth = it.width
+
+                            // 清空旧点
                             mStationList.clear()
-                            val location = IntArray(2)
-                            mBinding?.mapview?.getLocationOnScreen(location)
-                            itMapInfo.pointList?.forEach { itPoint ->
-                                val locationX =
-                                    (itPoint.x!!.toFloat() - (itMapInfo.x!!.toFloat() / 50)) * 50 / itMapInfo.width!!.toFloat() * it.width
-                                val locationY =
-                                    (itPoint.y!!.toFloat() + 1 - itMapInfo.y!!.toFloat() / 50) * 50 / itMapInfo.height!!.toFloat() * it.height
+
+                            // 1 格 对应的像素
+                            val cellPx = 50f
+                            // 后端给的“逻辑”子图原始尺寸(像素)
+                            val backendW = itMapInfo.width!!.toFloat()
+                            val backendH = itMapInfo.height!!.toFloat()
+                            // 实际下载回来的 Bitmap 尺寸(像素)
+                            val actualW = mapBmp.width.toFloat()
+                            val actualH = mapBmp.height.toFloat()
+                            // 计算缩放比例
+                            val ratioX = actualW / backendW
+                            val ratioY = actualH / backendH
+                            mapRatio = ratioX
+                            // 子图在全局坐标系里的左上角偏移(像素)
+                            val offsetX = itMapInfo.x!!.toFloat()
+                            val offsetY = itMapInfo.y!!.toFloat()
+                            // 图标请求尺寸:逻辑 45px * 缩放比
+                            val iconReqPx = (45f * ratioX).toInt().coerceAtLeast(1)
+
+                            itMapInfo.pointList?.forEach { pt ->
+                                // 1) 格数 → 全局像素
+                                val globalX = pt.x!!.toFloat() * cellPx
+                                val globalY = pt.y!!.toFloat() * cellPx
+                                // 2) 全局像素 - 子图偏移 = 子图内像素
+                                val localX = globalX - offsetX
+                                val localY = globalY - offsetY
+                                // 3) 再乘缩放比,得到真实 Bitmap 上的像素坐标
+                                val finalX = localX * ratioX
+                                val finalY = localY * ratioY
+                                // 异步加载点位图标,固定请求尺寸
                                 BitmapUtil.loadBitmapFromUrl(
                                     requireContext(),
-                                    itPoint.pointIcon!!,
-                                    reqWidth = 18,
-                                    reqHeight = 18
-                                ) { itBitmap ->
+                                    pt.pointIcon!!,
+                                    reqWidth = iconReqPx,
+                                    reqHeight = iconReqPx
+                                ) { bmpIcon ->
+                                    val icon = bmpIcon ?: BitmapUtil.getResizedBitmapFromMipmap(
+                                        requireContext(),
+                                        R.mipmap.ticket_type_placeholder,
+                                        iconReqPx,
+                                        iconReqPx
+                                    )
+
                                     mStationList.add(
                                         CustomStationLayer.IsolationPoint(
-                                            PointF(locationX, locationY),
-                                            itPoint.entityName!!,
-                                            itBitmap ?: BitmapUtil.getResizedBitmapFromMipmap(
-                                                requireContext(),
-                                                R.mipmap.ticket_type_placeholder,
-                                                18,
-                                                18
-                                            ),
-                                            itPoint.entityId!!,
-                                            mMachineryDetail?.pointIdList?.contains(itPoint.entityId) == true
+                                            PointF(finalX, finalY),
+                                            pt.entityName!!,
+                                            icon,
+                                            pt.entityId!!.toLong(),
+                                            mMachineryDetail?.pointIdList?.contains(pt.entityId) == true
                                         )
                                     )
+
+                                    // 全部点都加载完后,设置给 layer 并绘制
                                     if (mStationList.size == itMapInfo.pointList.size) {
-                                        mBinding?.mapview?.loadMap(it)
+                                        mBinding?.mapview?.loadMap(mapBmp)
                                     }
                                 }
                             }
@@ -347,8 +378,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                 else -> ""
             }
             if (step == 8 && presenter?.checkCrossJobUnlockData(
-                    requireContext(),
-                    mTicketDetailData
+                    requireContext(), mTicketDetailData
                 ) == true
             ) {
                 mTipDialog.setTip(getString(R.string.all_point_have_other_job_not_finish))
@@ -358,8 +388,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                         presenter?.updateCoincideToUnLock(it) {
                             if (it) {
                                 presenter?.updateStep(
-                                    mStepList.find { it.index == step }?.stepDetail?.stepId!!,
-                                    "1"
+                                    mStepList.find { it.index == step }?.stepDetail?.stepId!!, "1"
                                 ) {
                                     mChangePage?.let {
                                         refreshPage(it)
@@ -382,8 +411,7 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                                     BusinessManager.sendLoadingEventMsg(null, false)
                                     refreshPage(mChangePage!!)
                                     if (presenter?.jumpJobProgressPageCheck(
-                                            requireContext(),
-                                            step
+                                            requireContext(), step
                                         ) == true
                                     ) {
                                         // 自动跳转
@@ -403,20 +431,21 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
 
                         else -> {
                             presenter?.updateStep(
-                                mStepList.find { it.index == step }?.stepDetail?.stepId!!,
-                                "1"
+                                mStepList.find { it.index == step }?.stepDetail?.stepId!!, "1"
                             ) {
                                 refreshPage(mChangePage!!)
                                 if (presenter?.jumpJobProgressPageCheck(
-                                        requireContext(),
-                                        step
+                                        requireContext(), step
                                     ) == true
                                 ) {
                                     // 自动跳转
                                     changePage(
                                         PageChangeBO(
-                                            2, mChangePage?.workstationId, mChangePage?.ticketId,
-                                            mChangePage?.machineryId, mChangePage?.machineryName
+                                            2,
+                                            mChangePage?.workstationId,
+                                            mChangePage?.ticketId,
+                                            mChangePage?.machineryId,
+                                            mChangePage?.machineryName
                                         )
                                     )
                                 }
@@ -432,8 +461,11 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                 presenter?.tipToJobProgressPageCheck(requireContext(), mStep) {
                     changePage(
                         PageChangeBO(
-                            2, mChangePage?.workstationId, mChangePage?.ticketId,
-                            mChangePage?.machineryId, mChangePage?.machineryName
+                            2,
+                            mChangePage?.workstationId,
+                            mChangePage?.ticketId,
+                            mChangePage?.machineryId,
+                            mChangePage?.machineryName
                         )
                     )
                 }

+ 81 - 46
app/src/main/java/com/grkj/iscs/view/widget/CustomStationLayer.kt

@@ -10,15 +10,16 @@ import android.util.Pair
 import android.view.MotionEvent
 import com.grkj.iscs.R
 import com.grkj.iscs.util.BitmapUtil
+import com.grkj.iscs.util.log.LogUtil
 import com.onlylemi.mapview.library.MapView
+import com.onlylemi.mapview.library.MapViewListener
 import com.onlylemi.mapview.library.layer.MapBaseLayer
 import java.util.Collections
 import kotlin.math.cos
 import kotlin.math.sin
 
 class CustomStationLayer @JvmOverloads constructor(
-    mapView: MapView?,
-    private var pointList: List<IsolationPoint> = mutableListOf()
+    mapView: MapView?, private var pointList: List<IsolationPoint> = mutableListOf()
 ) : MapBaseLayer(mapView) {
     private var listener: MarkIsClickListener? = null
     private var radiusMark = 0f
@@ -28,75 +29,103 @@ class CustomStationLayer @JvmOverloads constructor(
     private var btnIndex: Int = -1
     private var currentZoom = 0f
     private var currentDegree = 0f
-    private lateinit var bgBitmap: Bitmap
-    private lateinit var coverBitmap: Bitmap
+    private var bgBitmap: Bitmap? = null
+    private var coverBitmap: Bitmap? = null
+    private var ratio: Float = 1f
 
     init {
         initLayer()
     }
 
     private fun initLayer() {
-        radiusMark = setValue(4.0f)
-        bgBitmap = BitmapUtil.getResizedBitmapFromMipmap(mapView.context, R.mipmap.red_stroke_bg, 24, 32)
-        coverBitmap = BitmapUtil.getResizedBitmapFromDrawable(mapView.context, R.drawable.map_item_cover_bg, 24, 32)!!
-
+        radiusMark = setValue(6.0f)
         paint = Paint()
         paint.isAntiAlias = true
         paint.style = Paint.Style.FILL_AND_STROKE
     }
 
+    fun setRatio(ratio: Float) {
+        this.ratio = ratio
+        bgBitmap = BitmapUtil.getResizedBitmapFromDrawable(
+            mapView.context,
+            R.drawable.red_stroke_bg,
+            (50 * ratio).toInt(),
+            (78 * ratio).toInt()
+        )!!
+        coverBitmap = BitmapUtil.getResizedBitmapFromDrawable(
+            mapView.context,
+            R.drawable.map_item_cover_bg,
+            (50 * ratio).toInt(),
+            (78 * ratio).toInt()
+        )!!
+    }
+
     override fun onTouch(event: MotionEvent) {
 
     }
 
     override fun draw(
-        canvas: Canvas,
-        currentMatrix: Matrix,
-        currentZoom: Float,
-        currentRotateDegrees: Float
+        canvas: Canvas, currentMatrix: Matrix, currentZoom: Float, currentRotateDegrees: Float
     ) {
         this.currentZoom = currentZoom
         currentDegree = 360 - currentRotateDegrees
-        if (isVisible) {
-            canvas.save()
-            synchronized(pointList) {
-                pointList.forEach { point ->
-                    val mark = point.pos
-                    val goal = floatArrayOf(mark.x, mark.y)
-                    currentMatrix.mapPoints(goal)
-
-                    // 文字背景
-                    val width = paint.measureText(point.entityName)
-                    paint.style = Paint.Style.FILL
-                    paint.strokeWidth = 1.0f
-
-                    paint.color = Color.parseColor("#CCFF0000")
-                    paint.textSize = radiusMark
-                    // 先画背景再画文字防止文字被盖住
-                    canvas.drawBitmap(bgBitmap, goal[0] - bgBitmap.width / 2, goal[1] - 2 * radiusMark, paint)
-                    point.icon?.let {
-                        canvas.drawBitmap(it, goal[0] - it.width / 2, goal[1] - 2  * radiusMark, paint)
+
+        if (!isVisible) return
+
+        canvas.save()
+        // 把 mapView 本身的缩放/平移/旋转一次性 concat 到 Canvas
+        canvas.concat(currentMatrix)
+        pointList.forEach { point ->
+            // point.pos.x/y 已经是「图内像素坐标」
+            val x = point.pos.x
+            val y = point.pos.y
+            // 先画背景(它会被 currentMatrix 自动缩放)
+            bgBitmap?.let {
+                canvas.drawBitmap(
+                    it, x, y, paint
+                )
+                // 再画 icon
+                point.icon?.let { icon ->
+                    canvas.drawBitmap(
+                        icon,
+                        x + (it.width - icon.width) / 2,
+                        y + (it.width - icon.width) / 2,
+                        paint
+                    )
+                }
+                // 然后画文字
+                paint.style = Paint.Style.FILL
+                paint.strokeWidth = 1f
+                paint.color = Color.RED
+                paint.textSize = radiusMark * ratio  // 这里是「图内」的文字大小,后面会跟着缩放
+                val textW = paint.measureText(point.entityName)
+                canvas.drawText(
+                    point.entityName,
+                    x + (it.width - textW) / 2,
+                    y + (it.height - radiusMark / 2 - it.height / 10),
+                    paint
+                )
+
+                // 如果选中,再叠加一个标记
+                if (point.isSelected) {
+                    coverBitmap?.let {
+                        canvas.drawBitmap(
+                            it, x, y, paint
+                        )
                     }
-                    // 一直显示文字
+                    val checkW = paint.measureText("√")
+                    paint.color = Color.WHITE
                     canvas.drawText(
-                        point.entityName,
-                        goal[0] - width / 2,
-                        goal[1] + radiusMark / 3.0f,
+                        "√",
+                        x + (it.width - checkW) / 2,
+                        y + (it.height / 2 + radiusMark / 2),
                         paint
                     )
-                    if (point.isSelected) {
-                        canvas.drawBitmap(coverBitmap, goal[0] - bgBitmap.width / 2, goal[1] - 2 * radiusMark, paint)
-                        val selectTextWidth = paint.measureText("√")
-                        paint.color = Color.parseColor("#FFFFFF")
-                        canvas.drawText("√", goal[0] - selectTextWidth / 2, goal[1] - radiusMark / 2, paint)
-                    }
-
-                    // 定位点,仅调试用,不要显示
-//                    canvas.drawCircle(goal[0], goal[1], 2f, paint)
                 }
             }
-            canvas.restore()
         }
+
+        canvas.restore()
     }
 
     private fun rotatePoint(
@@ -120,5 +149,11 @@ class CustomStationLayer @JvmOverloads constructor(
         fun markIsClick(index: Int, btnIndex: Int)
     }
 
-    data class IsolationPoint(val pos: PointF, val entityName: String, val icon: Bitmap?, val entityId: Long, val isSelected: Boolean)
+    data class IsolationPoint(
+        val pos: PointF,
+        val entityName: String,
+        val icon: Bitmap?,
+        val entityId: Long,
+        val isSelected: Boolean
+    )
 }

+ 21 - 0
app/src/main/res/drawable/red_stroke_bg.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <item>
+        <shape android:shape="rectangle">
+            <solid android:color="@color/white" />
+            <size
+                android:width="50dp"
+                android:height="78dp" />
+            <corners android:radius="2.5dp" />
+        </shape>
+    </item>
+    <item>
+        <shape android:shape="rectangle">
+            <stroke
+                android:width="1dp"
+                android:color="@color/common_status_red" />
+            <corners android:radius="2.5dp" />
+        </shape>
+    </item>
+</layer-list>