要实现 OSMDroid 中批量加载标记和弹窗,且弹窗位置随着标记位置变化而变化,可以按照以下步骤进行操作:

  1. 创建一个ItemizedOverlayWithBubble类,继承自ItemizedOverlay,用于管理标记和弹窗的显示。
public class ItemizedOverlayWithBubble extends ItemizedOverlay<OverlayItem> {

    private ArrayList<OverlayItem> overlayItems;
    private Context context;

    public ItemizedOverlayWithBubble(Drawable defaultMarker, Context context) {
        super(boundCenterBottom(defaultMarker));
        overlayItems = new ArrayList<>();
        this.context = context;
    }

    public void addOverlayItem(OverlayItem overlayItem) {
        overlayItems.add(overlayItem);
        populate(); // 刷新标记
    }

    @Override
    protected OverlayItem createItem(int index) {
        return overlayItems.get(index);
    }

    @Override
    public int size() {
        return overlayItems.size();
    }

    @Override
    protected boolean onTap(int index) {
        OverlayItem item = overlayItems.get(index);
        // 创建弹窗
        InfoWindow infoWindow = new MyInfoWindow(R.layout.custom_info_window, map, item);
        // 显示弹窗
        infoWindow.open(item.getPoint(), 0, 0);
        return true;
    }

    // 自定义弹窗类
    private class MyInfoWindow extends InfoWindow {

        public MyInfoWindow(int layoutResId, MapView mapView, OverlayItem item) {
            super(layoutResId, mapView);
            // 设置弹窗内容
            TextView title = (TextView) mView.findViewById(R.id.title);
            title.setText(item.getTitle());
            TextView snippet = (TextView) mView.findViewById(R.id.snippet);
            snippet.setText(item.getSnippet());
        }

        @Override
        public void onOpen(Object arg0) {
            // 在标记上显示弹窗
            OverlayItem item = (OverlayItem) arg0;
            GeoPoint geoPoint = item.getPoint();
            IGeoPoint position = mapView.getProjection().toPixels(geoPoint, null);
            int x = position.x - mView.getWidth() / 2;
            int y = position.y - mView.getHeight();
            mView.setLayoutParams(new MapView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, new GeoPoint(0, 0), MapView.LayoutParams.BOTTOM_CENTER, x, y));
        }

        @Override
        public void onClose() {
            // 关闭弹窗
        }
    }
}
  1. onCreate方法中初始化地图,并创建ItemizedOverlayWithBubble对象。
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    MapView mapView = (MapView) findViewById(R.id.mapview);
    mapView.setTileSource(TileSourceFactory.MAPNIK);
    mapView.setMultiTouchControls(true);

    // 创建ItemizedOverlayWithBubble对象
    Drawable defaultMarker = getResources().getDrawable(R.drawable.marker);
    ItemizedOverlayWithBubble overlay = new ItemizedOverlayWithBubble(defaultMarker, this);

    // 添加标记
    OverlayItem item1 = new OverlayItem('Title1', 'Snippet1', new GeoPoint(0, 0));
    overlay.addOverlayItem(item1);
    OverlayItem item2 = new OverlayItem('Title2', 'Snippet2', new GeoPoint(10, 10));
    overlay.addOverlayItem(item2);

    // 添加ItemizedOverlayWithBubble到地图
    mapView.getOverlays().add(overlay);
}

这样就可以在地图上批量加载标记和弹窗,并且弹窗位置会随着标记位置的变化而变化。在点击标记时,会显示对应的弹窗。


原文地址: https://www.cveoy.top/t/topic/o2YS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录