求助:Google Maps自定义InfoWindow中Rating Bar显示异常问题
嘿,我太懂你遇到的这个坑了!自定义InfoWindow里的Rating Bar总是显示最后一条数据库数据,这在Google Maps开发里真的很常见,核心问题出在InfoWindow的渲染逻辑和视图复用的细节上。
问题根源
Google Maps的InfoWindow并不是真正的可交互Android View——它会把你自定义的View转换成一张静态Bitmap来展示。如果你的InfoWindowAdapter里复用了同一个View实例,每次更新数据时都会覆盖之前的内容,最后所有窗口都会显示最后一次设置的Rating值。而且因为Bitmap是缓存的,这个问题会显得特别顽固。
解决方案
我们需要从两个方面入手:避免视图复用+给每个Marker绑定专属数据,具体步骤如下:
1. 修改CustomInfoWindowAdapter,每次创建新的InfoWindow View
不要在Adapter里持有全局的View实例,每次调用getInfoContents时都重新inflate布局,这样每个InfoWindow都有自己独立的View,不会被之前的数据污染。
public class CustomInfoWindowAdapter implements GoogleMap.InfoWindowAdapter { private final LayoutInflater inflater; // 构造器只传入LayoutInflater,不持有全局View public CustomInfoWindowAdapter(Context context) { inflater = LayoutInflater.from(context); } @Override public View getInfoWindow(Marker marker) { return null; // 保留默认的窗口边框,用getInfoContents填充内容 } @Override public View getInfoContents(Marker marker) { // 每次都创建新的View实例 View infoView = inflater.inflate(R.layout.your_info_window_layout, null); // 获取当前Marker对应的Rating值(后面会说怎么绑定) Float placeRating = (Float) marker.getTag(); if (placeRating != null) { RatingBar ratingBar = infoView.findViewById(R.id.rating_bar); ratingBar.setRating(placeRating); // 记得把RatingBar设为指示器,因为InfoWindow是静态的,用户点不了 ratingBar.setIsIndicator(true); } // 顺便设置其他内容,比如地点名称、地址 TextView titleTv = infoView.findViewById(R.id.tv_place_title); titleTv.setText(marker.getTitle()); TextView addressTv = infoView.findViewById(R.id.tv_place_address); addressTv.setText(marker.getSnippet()); return infoView; } }
2. 给每个Marker绑定对应的Rating数据
在你从JSON接口获取数据并添加Marker的时候,把当前地点的Rating值存入Marker的Tag中,这样在Adapter里就能精准拿到每个Marker对应的数据:
// 假设你解析后的地点数据是Place对象,包含rating字段 for (Place place : yourPlaceList) { LatLng location = new LatLng(place.getLat(), place.getLng()); Marker marker = googleMap.addMarker(new MarkerOptions() .position(location) .title(place.getName()) .snippet(place.getAddress())); // 把当前地点的Rating绑定到Marker的Tag上 marker.setTag(place.getRating()); } // 最后设置自定义Adapter googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
3. 优化布局里的RatingBar
在你的InfoWindow布局文件中,记得把RatingBar设为不可交互,因为InfoWindow是静态Bitmap,用户无法拖动RatingBar,设置成指示器更合理:
<RatingBar android:id="@+id/rating_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="5" android:stepSize="0.1" android:isIndicator="true" android:rating="0"/>
为什么这样能解决问题?
每次创建新的View实例,就不会出现“一个View被多次赋值最后只保留最后一次数据”的情况;而通过Marker的Tag绑定专属Rating,能确保每个InfoWindow都拿到自己对应地点的评分,彻底解决数据混淆的问题。
内容的提问来源于stack exchange,提问作者Tarik M'ghari

