【问题标题】:Android Kotlin - Implement custom map marker using Bitmap with GlideAndroid Kotlin - 使用带有 Glide 的位图实现自定义地图标记
【发布时间】:2019-03-26 14:11:07
【问题描述】:

我正在尝试使用我的 XML 布局在 Google 地图中实现自定义地图标记。

但是;当我使用createCustomMarker 方法将我的自定义标记打印到谷歌地图时,它不会加载/显示来自云/服务器的图像。

我认为这是因为 Glide(或这件事中的应用程序)没有在布局转换为位图之前完成下载和渲染图像的更改,或者我的实现可能是错误的。谁能帮我这个?

@SuppressLint("InflateParams")
    private fun createCustomMarker(urlImageFromCloud: String): Bitmap{

        val marker: LayoutInflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val view: View = marker.inflate(R.layout.map_marker, null)

        val messageIcon: Int = resources.getIdentifier("local_image_from_drawable", "drawable", this.packageName)
        val markerPhoto: CircleImageView = view.findViewById(R.id.map_photo)
        val markerContainer: CircleImageView = view.findViewById(R.id.map_photo)
        val options: RequestOptions = RequestOptions()
            .centerCrop()
            .placeholder(R.color.colorGrayWhite)
            .error(R.color.colorGrayWhite)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
        Glide.with(this)
            .load(urlImageFromCloud) // String image URL from my server/cloud - this is the part that does not show up.
            .apply(options).into(markerPhoto)
        Glide.with(this)
            .load(messageIcon)
            .apply(options).into(markerContainer)


        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)

        view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels)
        view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
        view.buildDrawingCache()
        val bitmap = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)

        return bitmap
    }

我的 map_marker XML :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/custom_marker_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    <ImageView
            android:id="@+id/map_container"
            android:layout_width="75dp"
            android:layout_height="75dp"/>

    <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/map_photo"
            android:src="@color/colorGray"
            android:layout_marginTop="5dp"
            android:layout_centerHorizontal="true"
            style="@style/MapMarkerCircleImage"/>


</RelativeLayout>

这就是我调用createCustomMarker 方法的方式。

val defaultLocation = LatLng(locationLatitude, locationLongitude)
googleMap.addMarker(MarkerOptions().position(defaultLocation).icon(BitmapDescriptorFactory.fromBitmap(createCustomMarker("my_image_url_from_cloud"))))

【问题讨论】:

  • 显然,问题是BitmapDescriptorFactory.fromBitmap不要拿Glide.into添加的图层,如果你使用Glide.asBitmap下载位图应该一切正常

标签: android google-maps kotlin android-glide android-bitmap


【解决方案1】:

我有同样的问题。我的解决方案只是使用 Glide 下载位图,并在下载完成时使用侦听器创建标记。

private fun getMarkerIcon(context: Context, url: String, listener: (BitmapDescriptor) -> Unit) {
    val markerView = View.inflate(context, R.layout.view_marker, null)
    Glide.with(context)
        .asBitmap()
        .load(url)
        .into(object : SimpleTarget<Bitmap>() {

            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                markerView.avatarImageView.setImageBitmap(resource)
                listener.invoke(BitmapDescriptorFactory.fromBitmap(getBitmapFromView(markerView)))
            }
        })
}

private fun getBitmapFromView(view: View): Bitmap {
    view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
    val bitmap = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    view.layout(0, 0, view.measuredWidth, view.measuredHeight)
    view.draw(canvas)
    return bitmap
}

还有电话

getMarkerIcon(context, "http://....") {
    val options = MarkerOptions()
        .position(LatLng(latitude, longitude))
        .icon(it)
    googleMap.addMarker(options)
}

【讨论】:

    【解决方案2】:

    您可以创建自定义ImageView 并从中获取BitmapDescriptor

    class CustomImageView @JvmOverloads constructor(context: Context,
                                                    attrs: AttributeSet? = null,
                                                    defStyle: Int = 0,
                                                    defStyleRes: Int = 0): ImageView(context, attrs, defStyle, defStyleRes) {
    
        init {
            setImageBitmap(createCustomMarker("my_image_url_from_cloud"))
        }
    
        private fun loadBitmapFromView(view: View): Bitmap {
            view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
            val bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
                    Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight())
            view.draw(canvas)
            return bitmap
        }
    
        fun getBitmapDescriptor(): BitmapDescriptor {
            val bitmap = CommonUtil.loadBitmapFromView(this)
            return BitmapDescriptorFactory.fromBitmap(bitmap)
        }
    }
    

    确保在获取BitmapDescriptor 之前将图像加载到视图中。

    我从this 的答案中得到了函数。

    【讨论】:

      猜你喜欢
      • 2016-09-21
      • 2020-03-27
      • 2018-01-13
      • 2017-07-10
      • 2016-09-20
      • 2023-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多