Android Kotlin-使用带有Glide的位图实现自定义地图标记

时间:2019-03-26 14:11:07

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

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

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

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

@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"))))

2 个答案:

答案 0 :(得分:0)

您可以创建自定义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答案中获得了功能。

答案 1 :(得分:0)

我有同样的问题。我的解决方案是仅使用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)
}