Ver Fonte

添加锁定站地图遮罩显示

Frankensteinly há 7 meses atrás
pai
commit
ba382d15ec

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

@@ -0,0 +1,167 @@
+package com.grkj.iscs.util
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.Canvas
+import android.os.Environment
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.DataSource
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.Target
+import com.grkj.iscs.util.log.LogUtil
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+
+
+object BitmapUtil {
+
+    fun bitmapToFile(bitmap: Bitmap, fileName: String): File? {
+        // 创建一个临时文件
+        val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+        if (!storageDir.exists()) {
+            storageDir.mkdirs()
+        }
+
+        val file = File(storageDir, fileName)
+
+        return try {
+            // 创建文件输出流
+            val fos = FileOutputStream(file)
+
+            // 将 Bitmap 压缩并写入文件
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
+
+            // 刷新并关闭输出流
+            fos.flush()
+            fos.close()
+
+            file
+        } catch (e: IOException) {
+            e.printStackTrace()
+            null
+        }
+    }
+
+    fun bitmapToByteArray(bitmap: Bitmap, format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG, quality: Int = 100): ByteArray {
+        val stream = ByteArrayOutputStream()
+
+        // 将 Bitmap 压缩并写入到 ByteArrayOutputStream 中
+        bitmap.compress(format, quality, stream)
+
+        // 获取字节数组
+        return stream.toByteArray()
+    }
+
+    fun loadBitmapFromUrl(ctx: Context, url: String, callback: (Bitmap?) -> Unit) {
+        try {
+            Glide.with(ctx)
+                .asBitmap()
+                .load(url)
+                .listener(object : RequestListener<Bitmap> {
+                    override fun onLoadFailed(
+                        e: GlideException?,
+                        model: Any?,
+                        target: Target<Bitmap>?,
+                        isFirstResource: Boolean
+                    ): Boolean {
+                        Executor.runOnMain {
+                            callback(null)
+                        }
+                        return false
+                    }
+
+                    override fun onResourceReady(
+                        resource: Bitmap?,
+                        model: Any?,
+                        target: Target<Bitmap>?,
+                        dataSource: DataSource?,
+                        isFirstResource: Boolean
+                    ): Boolean {
+                        Executor.runOnMain {
+                            callback(resource)
+                        }
+                        return false
+                    }
+                })
+                .submit()
+        } catch (e: Exception) {
+            e.printStackTrace()
+            Executor.runOnMain {
+                callback(null)
+            }
+        }
+    }
+
+    fun getResizedBitmapFromMipmap(
+        context: Context,
+        resId: Int,
+        reqWidth: Int,
+        reqHeight: Int
+    ): Bitmap {
+        // First decode with inJustDecodeBounds=true to check dimensions
+        val options = BitmapFactory.Options()
+        options.inJustDecodeBounds = true
+        BitmapFactory.decodeResource(context.resources, resId, options)
+
+        // Calculate inSampleSize
+        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
+
+        // Decode bitmap with inSampleSize set
+        options.inJustDecodeBounds = false
+        val scaledBitmap = BitmapFactory.decodeResource(context.resources, resId, options)
+
+        // Resize the bitmap if necessary
+        return Bitmap.createScaledBitmap(scaledBitmap, reqWidth, reqHeight, false)
+    }
+
+    private fun calculateInSampleSize(
+        options: BitmapFactory.Options,
+        reqWidth: Int,
+        reqHeight: Int
+    ): Int {
+        // Raw height and width of image
+        val height = options.outHeight
+        val width = options.outWidth
+        var inSampleSize = 1
+
+        if (height > reqHeight || width > reqWidth) {
+            val halfHeight = height / 2
+            val halfWidth = width / 2
+
+            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
+            // height and width larger than the requested height and width.
+            while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
+                inSampleSize *= 2
+            }
+        }
+
+        return inSampleSize
+    }
+
+    fun getResizedBitmapFromDrawable(
+        context: Context,
+        resId: Int,
+        reqWidth: Int,
+        reqHeight: Int
+    ): Bitmap? {
+        val drawable = context.resources.getDrawable(resId)
+        if (drawable == null) {
+            LogUtil.e("Drawable is null for resource ID: $resId")
+            return null
+        }
+
+        // Create a bitmap with the specified width and height
+        val bitmap = Bitmap.createBitmap(reqWidth, reqHeight, Bitmap.Config.ARGB_8888)
+        val canvas = Canvas(bitmap)
+
+        // Scale the drawable to fit the bitmap dimensions
+        drawable.setBounds(0, 0, reqWidth, reqHeight)
+        drawable.draw(canvas)
+
+        return bitmap
+    }
+}

+ 0 - 88
app/src/main/java/com/grkj/iscs/util/CommonUtils.kt

@@ -6,22 +6,11 @@ import android.Manifest.permission.BLUETOOTH_ADVERTISE
 import android.Manifest.permission.BLUETOOTH_CONNECT
 import android.Manifest.permission.BLUETOOTH_SCAN
 import android.content.Context
-import android.graphics.Bitmap
 import android.os.Build
-import android.os.Environment
 import androidx.appcompat.app.AppCompatActivity
-import com.bumptech.glide.Glide
-import com.bumptech.glide.load.DataSource
-import com.bumptech.glide.load.engine.GlideException
-import com.bumptech.glide.request.RequestListener
-import com.bumptech.glide.request.target.Target
 import com.grkj.iscs.MyApplication
 import com.grkj.iscs.model.Constants.PERMISSION_REQUEST_CODE
 import pub.devrel.easypermissions.EasyPermissions
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.io.FileOutputStream
-import java.io.IOException
 import java.text.SimpleDateFormat
 import java.util.Locale
 
@@ -93,81 +82,4 @@ object CommonUtils {
     fun isValidHex(hexString: String): Boolean {
         return hexRegex.matches(hexString)
     }
-
-    fun bitmapToFile(bitmap: Bitmap, fileName: String): File? {
-        // 创建一个临时文件
-        val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
-        if (!storageDir.exists()) {
-            storageDir.mkdirs()
-        }
-
-        val file = File(storageDir, fileName)
-
-        return try {
-            // 创建文件输出流
-            val fos = FileOutputStream(file)
-
-            // 将 Bitmap 压缩并写入文件
-            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
-
-            // 刷新并关闭输出流
-            fos.flush()
-            fos.close()
-
-            file
-        } catch (e: IOException) {
-            e.printStackTrace()
-            null
-        }
-    }
-
-    fun bitmapToByteArray(bitmap: Bitmap, format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG, quality: Int = 100): ByteArray {
-        val stream = ByteArrayOutputStream()
-
-        // 将 Bitmap 压缩并写入到 ByteArrayOutputStream 中
-        bitmap.compress(format, quality, stream)
-
-        // 获取字节数组
-        return stream.toByteArray()
-    }
-
-    fun loadBitmapFromUrl(ctx: Context, url: String, callback: (Bitmap?) -> Unit) {
-        try {
-            Glide.with(ctx)
-                .asBitmap()
-                .load(url)
-                .listener(object : RequestListener<Bitmap> {
-                    override fun onLoadFailed(
-                        e: GlideException?,
-                        model: Any?,
-                        target: Target<Bitmap>?,
-                        isFirstResource: Boolean
-                    ): Boolean {
-                        Executor.runOnMain {
-                            callback(null)
-                        }
-                        return false
-                    }
-
-                    override fun onResourceReady(
-                        resource: Bitmap?,
-                        model: Any?,
-                        target: Target<Bitmap>?,
-                        dataSource: DataSource?,
-                        isFirstResource: Boolean
-                    ): Boolean {
-                        Executor.runOnMain {
-                            callback(resource)
-                        }
-                        return false
-                    }
-                })
-                .submit()
-        } catch (e: Exception) {
-            e.printStackTrace()
-            Executor.runOnMain {
-                callback(null)
-            }
-        }
-    }
 }

+ 3 - 8
app/src/main/java/com/grkj/iscs/view/fragment/StepFragment.kt

@@ -13,7 +13,7 @@ import com.grkj.iscs.model.bo.PageChangeBO
 import com.grkj.iscs.model.vo.machinery.MachineryDetailRespVO
 import com.grkj.iscs.model.vo.ticket.LotoMapRespVO
 import com.grkj.iscs.model.vo.ticket.StepDetailRespVO
-import com.grkj.iscs.util.CommonUtils
+import com.grkj.iscs.util.BitmapUtil
 import com.grkj.iscs.util.ToastUtils
 import com.grkj.iscs.util.log.LogUtil
 import com.grkj.iscs.view.base.BaseMvpFragment
@@ -211,32 +211,27 @@ class StepFragment(val goBack: () -> Unit, val changePage: (PageChangeBO) -> Uni
                 mLotoList[0].mapId?.let { itId ->
                     presenter?.getMapInfo(itId) { itMapInfo ->
                         itMapInfo?.imageUrl ?: return@getMapInfo
-                        CommonUtils.loadBitmapFromUrl(requireContext(), itMapInfo.imageUrl) {
+                        BitmapUtil.loadBitmapFromUrl(requireContext(), itMapInfo.imageUrl) {
                             if (it == 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
-                                
                                 mStationList.add(
                                     CustomStationLayer.IsolationPoint(
                                         PointF(locationX, locationY),
                                         itPoint.entityName!!,
                                         itPoint.entityId!!,
-                                        mLotoList.any { it.entityId == itPoint.entityId }
+                                        mMachineryDetail?.pointIdList?.contains(itPoint.entityId) == true
                                     )
                                 )
                             }
-
                             mBinding?.mapview?.loadMap(it)
                         }
                     }

+ 2 - 2
app/src/main/java/com/grkj/iscs/view/fragment/WorkshopFragment.kt

@@ -7,7 +7,7 @@ import com.grkj.iscs.databinding.FragmentWorkshopBinding
 import com.grkj.iscs.model.Constants
 import com.grkj.iscs.model.bo.PageChangeBO
 import com.grkj.iscs.model.vo.ticket.WorkstationTicketListRespVO
-import com.grkj.iscs.util.CommonUtils
+import com.grkj.iscs.util.BitmapUtil
 import com.grkj.iscs.util.ToastUtils
 import com.grkj.iscs.util.log.LogUtil
 import com.grkj.iscs.view.base.BaseMvpFragment
@@ -60,7 +60,7 @@ class WorkshopFragment(val changePage: (PageChangeBO) -> Unit) :
 
     fun refreshPage() {
         presenter?.getMapInfo {
-            CommonUtils.loadBitmapFromUrl(requireContext(), it?.imageUrl!!) {
+            BitmapUtil.loadBitmapFromUrl(requireContext(), it?.imageUrl!!) {
                 if (it == null) {
                     LogUtil.e("Map pic is null")
                     return@loadBitmapFromUrl

+ 2 - 2
app/src/main/java/com/grkj/iscs/view/presenter/LoginPresenter.kt

@@ -11,7 +11,7 @@ import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_CARD
 import com.grkj.iscs.model.vo.FileStreamReqParam
 import com.grkj.iscs.model.vo.card.CardInfoRespVO
 import com.grkj.iscs.model.vo.user.UserInfoRespVO
-import com.grkj.iscs.util.CommonUtils
+import com.grkj.iscs.util.BitmapUtil
 import com.grkj.iscs.util.Executor
 import com.grkj.iscs.util.NetApi
 import com.grkj.iscs.util.SPUtils
@@ -68,7 +68,7 @@ class LoginPresenter : BasePresenter<ILoginView>() {
     }
 
     fun fingerprintLogin(bitmap: Bitmap, callBack: (Boolean, CardInfoRespVO?, UserInfoRespVO?) -> Unit) {
-        NetApi.loginByFingerprint(mutableListOf(FileStreamReqParam("file", CommonUtils.bitmapToByteArray(bitmap), ".bmp"))) {
+        NetApi.loginByFingerprint(mutableListOf(FileStreamReqParam("file", BitmapUtil.bitmapToByteArray(bitmap), ".bmp"))) {
             if (it) {
                 NetApi.getUserInfo { userInfo ->
                     NetApi.getCardInfoByLoginUser { itInfo ->

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

@@ -11,6 +11,7 @@ import android.graphics.PointF
 import android.util.Pair
 import android.view.MotionEvent
 import com.grkj.iscs.R
+import com.grkj.iscs.util.BitmapUtil
 import com.onlylemi.mapview.library.MapView
 import com.onlylemi.mapview.library.layer.MapBaseLayer
 import kotlin.math.cos
@@ -30,6 +31,7 @@ class CustomStationLayer @JvmOverloads constructor(
     private var currentZoom = 0f
     private var currentDegree = 0f
     private lateinit var bgBitmap: Bitmap
+    private lateinit var coverBitmap: Bitmap
 
 
     init {
@@ -40,58 +42,15 @@ class CustomStationLayer @JvmOverloads constructor(
 
     private fun initLayer() {
         radiusMark = setValue(4.0f)
-        bgBitmap = getResizedBitmapFromMipmap(mapView.context, R.mipmap.red_stroke_bg, 24, 32)
+        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)!!
 
         paint = Paint()
         paint.isAntiAlias = true
         paint.style = Paint.Style.FILL_AND_STROKE
     }
 
-    private fun getResizedBitmapFromMipmap(
-        context: Context,
-        resId: Int,
-        reqWidth: Int,
-        reqHeight: Int
-    ): Bitmap {
-        // First decode with inJustDecodeBounds=true to check dimensions
-        val options = BitmapFactory.Options()
-        options.inJustDecodeBounds = true
-        BitmapFactory.decodeResource(context.resources, resId, options)
-
-        // Calculate inSampleSize
-        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
-
-        // Decode bitmap with inSampleSize set
-        options.inJustDecodeBounds = false
-        val scaledBitmap = BitmapFactory.decodeResource(context.resources, resId, options)
-
-        // Resize the bitmap if necessary
-        return Bitmap.createScaledBitmap(scaledBitmap, reqWidth, reqHeight, false)
-    }
 
-    private fun calculateInSampleSize(
-        options: BitmapFactory.Options,
-        reqWidth: Int,
-        reqHeight: Int
-    ): Int {
-        // Raw height and width of image
-        val height = options.outHeight
-        val width = options.outWidth
-        var inSampleSize = 1
-
-        if (height > reqHeight || width > reqWidth) {
-            val halfHeight = height / 2
-            val halfWidth = width / 2
-
-            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
-            // height and width larger than the requested height and width.
-            while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
-                inSampleSize *= 2
-            }
-        }
-
-        return inSampleSize
-    }
 
     override fun onTouch(event: MotionEvent) {
         if (pointList.isNotEmpty()) {
@@ -146,7 +105,7 @@ class CustomStationLayer @JvmOverloads constructor(
                     paint.color = Color.parseColor("#CCFF0000")
                     paint.textSize = radiusMark
                     // 先画背景再画文字防止文字被盖住
-                    canvas.drawBitmap(bgBitmap, goal[0] - width / 2, goal[1] - 2 * radiusMark, paint)
+                    canvas.drawBitmap(bgBitmap, goal[0] - bgBitmap.width / 2, goal[1] - 2 * radiusMark, paint)
                     // 一直显示文字
                     canvas.drawText(
                         point.entityName,
@@ -154,6 +113,12 @@ class CustomStationLayer @JvmOverloads constructor(
                         goal[1] + radiusMark / 3.0f,
                         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)

+ 5 - 0
app/src/main/res/drawable/map_item_cover_bg.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <corners android:radius="@dimen/divider_line_width" />
+    <solid android:color="@color/common_bg_black_30" />
+</shape>