如何在Android中使用Glide加载图片到Google Maps的infoWindow?

5
我正在使用谷歌地图开发应用程序。 我需要自定义信息窗口,其中包含两个文本和图片来源。
这是我的infocontents()代码。 使用Firebase、Google地图和Glide,但它没有起作用,请帮忙解决。
  @Override
    public View getInfoWindow(Marker marker) {
        return null;
    }

    @Override
    public View getInfoContents(Marker marker) {
        final View v = getLayoutInflater().inflate(R.layout.custom_window, null);

        infoWindowProfile = (CircleImageView) v.findViewById(R.id.ci_custom_profile);
        infoWindowPr = (TextView) v.findViewById(R.id.tv_custom_pr);
        String uidTemp = marker.getSnippet();
        Log.d("markerproper", "uid(snippet) : " + uidTemp);
        database = FirebaseDatabase.getInstance();
        markerRef = database.getReference().child("truck").child(uidTemp);
        markerRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Map<String, ZariPosts> zariPost = (Map<String, ZariPosts>) dataSnapshot.getValue();
                markerProfileUrl = String.valueOf(zariPost.get("profileUrl"));
                markerPr = String.valueOf(zariPost.get("pr"));
                Log.d("markerproper", "uid(markerProfileUrl) : " + markerProfileUrl);
                Log.d("markerproper", "uid(markerPr) : " + markerPr);


                Glide.with(SearchActivity.this)
                        .load(markerProfileUrl)
                        .centerCrop()
                        .into(infoWindowProfile);

                infoWindowPr.setText(markerPr);
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
        return v;
    }

请参考此链接:http://androidfreakers.blogspot.in/2013/08/display-custom-info-window-with.html。 - Avantika Saini
可能是一个重复问题,与http://stackoverflow.com/questions/16572971/how-to-add-image-into-infowindow-of-marker-in-google-maps-api-v2-android?rq=1相似。 - abielita
4个回答

8

来自 https://github.com/bumptech/glide/issues/290

您可以尝试将以下内容添加到您的getInfoContent()方法中。根据需要更改URL和imageView名称。

Glide.with(mContext).load(imageURL).asBitmap().override(50,50).listener(new RequestListener<String, Bitmap>() {
    @Override
    public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
        e.printStackTrace();
        return false;
    }

    @Override
    public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
        if(!isFromMemoryCache) marker.showInfoWindow();
        return false;
    }
}).into(imageView);

由于isFromMemoryCache变量不再存在,因此在版本4.7.1上无法工作。 - Tiago Elias
2
@TiagoElias 只需检查 !dataSource.equals(DataSource.MEMORY_CACHE) 是否成立。 - Serega
@Serega 我最终使用了Picasso库来完成这个!无论如何还是谢谢你。 - Tiago Elias

0

Kotlin修复:

首先,非常感谢所有为这个问题以及其他类似问题做出贡献的人。我能够通过拼凑代码来让它工作。 如果您正在使用Glide并遇到此问题,请看看我所使用的内容,我正在使用一个自定义信息窗口,并将数据类设置为标记的标签。

class CompanyMarkerCustomInfoWindow(val context: Context) : GoogleMap.InfoWindowAdapter {

override fun getInfoWindow(marker: Marker?): View? {
    return null
}

override fun getInfoContents(marker: Marker): View {
    val layoutInflater = (context as Activity).layoutInflater
    val binding = ItemCompanyMapMarkerBinding.inflate(layoutInflater)
    val infoWindowData: CompanyMapMarkerModel? = marker.tag as CompanyMapMarkerModel?
    binding.model = infoWindowData
    binding.executePendingBindings()

    if (infoWindowData?.loadImage != null) {
        val finalImageUrl = Constants.BASE_URL + infoWindowData.loadImage
        Glide.with(context)
            .load(finalImageUrl)
            .placeholder(R.drawable.ic_baseline_broken_image_24)
            .listener(MarkerCallback(marker))
            .into(binding.loadImage)
    }

    if (infoWindowData?.companyImage != null) {
        val finalImageUrl = Constants.BASE_URL + infoWindowData.companyImage
        Glide.with(context)
            .load(finalImageUrl)
            .placeholder(R.drawable.ic_baseline_broken_image_24)
            .listener(MarkerCallback(marker))
            .into(binding.companyProfileImage)
    }

    return binding.root
}

class MarkerCallback internal constructor(marker: Marker?) :
    RequestListener<Drawable> {

    var marker: Marker? = null

    private fun onSuccess() {
        if (marker != null && marker!!.isInfoWindowShown) {
            marker!!.hideInfoWindow()
            marker!!.showInfoWindow()
        }
    }

    init {
        this.marker = marker
    }

    override fun onLoadFailed(
        e: GlideException?,
        model: Any?,
        target: Target<Drawable>?,
        isFirstResource: Boolean
    ): Boolean {
        Log.e(javaClass.simpleName, "Error loading thumbnail! -> $e")
        return false
    }

    override fun onResourceReady(
        resource: Drawable?,
        model: Any?,
        target: Target<Drawable>?,
        dataSource: DataSource?,
        isFirstResource: Boolean
    ): Boolean {
        onSuccess()
        return false
    }
}

}

映射结果

enter image description here


我还没有尝试过你的解决方案,但我想知道:当你完全放大并保持信息窗口打开时,是否会陷入无限循环? - ThanosFisherman
@ThanosFisherman 这是一个很好的问题,我从来没有遇到过视图或卡顿的问题,而且已经有一段时间没有在这个项目上工作了,但我也很好奇。我会确保在某个时候加入一个换行符,并看看我能得出什么结论。 - LucidSoftworksLLC
我之所以问这个问题,是因为我曾尝试使用 Coil 来采用类似的方法,但最终陷入了无限循环,应用程序最终崩溃了。我刚刚尝试了您使用 Glide 的解决方案,效果非常好!没有卡顿,也没有由于无限循环而导致的崩溃。我怀疑 Coil 存在问题。可能与此有关 https://github.com/coil-kt/coil/issues/542 - ThanosFisherman

0
使用Picasso解决了我的问题,即图片在第一次加载时无法显示。这是在CustomInfoAdapter类中实现的。
override fun getInfoWindow(marker: Marker): View? {
    // This function is required, but can return null if
    // not replacing the entire info window

    // Set the marker's title and snippet to the appropriate text view
    // in the layout created.

    val titleView = contents.findViewById<TextView>(R.id.title)
    titleView.text = marker.title.split("https://")[0] ?: ""

    val phoneView = contents.findViewById<TextView>(R.id.phone)
    phoneView.text = marker.snippet ?: ""
    val userImage = contents.findViewById<ImageView>(R.id.profile_image)
    val photoUri = "https://${marker.title.split("https://")[1]}"
    Log.d("InfoWindowAdapter", "getInfoContents: $photoUri")

    Picasso.with(userImage.context)
        .load(photoUri)
        .placeholder(R.drawable.loading_status_animation)
        .error(R.drawable.ic_error_image)
        .into(userImage, object : Callback {
            override fun onSuccess() {
                if (marker.isInfoWindowShown) {
                    marker.hideInfoWindow()
                    marker.showInfoWindow()
                }
            }

            override fun onError() {
                Log.d("InfoWindow", "onError: An error occured")
            }
        })
    return contents

}

0

以下是简单易懂的 Kotlin 解决方案(取自 https://github.com/bumptech/glide/issues/290):

    //initiate those two variables
    private val images: HashMap<Marker, Bitmap> = HashMap()
    private val targets: HashMap<Marker, CustomTarget<Bitmap>> = HashMap()

    //create this inner class
    inner class InfoTarget(var marker: Marker) : CustomTarget<Bitmap>() {
        override fun onLoadCleared(@Nullable placeholder: Drawable?) {
            images.remove(marker)
        }

        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
            images.put(marker, resource)
            marker.showInfoWindow()
        }
    }
    
    //Create this method
    private fun getTarget(marker: Marker): CustomTarget<Bitmap> {
        var target = targets[marker]
        if (target == null) {
            target = InfoTarget(marker)
            targets[marker] = target // missing in original (fixed 2018 August)
        }
        return target
    }

//insert image here (in your acctual population code)
val image = images[marker]
if (image == null) {
    Glide.with(activity)
        .asBitmap()
        .load(pic_url)
        .dontAnimate()
        .into(getTarget(marker))
} else {
    imageView.setImageBitmap(image)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接