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

问题描述 投票:1回答:2

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

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

我认为这是因为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"))))
android google-maps kotlin android-glide android-bitmap
2个回答
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回答了这些功能。


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)
}
© www.soinside.com 2019 - 2024. All rights reserved.