MapContainer 上的 URLImage 未在实际设备上显示并在模拟器中闪烁

URLImage on MapContainer not displayed on actual device and flickering in simulator

我的应用有一张地图,用户的头像显示在中央,用户移动地图时应在其中添加包括照片在内的标记。

在模拟器上,添加了标记,但一旦我释放指针,图像就会消失,然后只剩下占位符(这就是我所说的闪烁)。在设备上,除了用户的头像外,什么也没有显示。

如您所见,图像不会保留在地图上,只有占位符会保留。用户图标在地图上位于南部,但已显示。

请注意:我没有收到 404 错误,地图上只有一个侦听器(见下文):

这是我触发地图更新的方式:

googleMap.addMapListener((source, zoom, center) -> {
                showReportsOnMap(googleMap, center, theme, currentForm, selectCategoryButton.getWidth());

});

这是我在地图上添加报告的方式:

public void showReportsOnMap(
        MapContainer currentMap,
        Coord center,
        Resources theme,
        Form f,
        int reportImageWidth) {

    /**
     * Get the map borders (CAUTION : it can be NaN)
     */
    Coord NE = currentMap.getCoordAtPosition(currentMap.getAbsoluteX() + currentMap.getWidth(), currentMap.getAbsoluteY());
    Coord SW = currentMap.getCoordAtPosition(currentMap.getAbsoluteX(), currentMap.getAbsoluteY() + currentMap.getHeight());

    boolean bordersKnownAndValid = false;

    // Checks that the borders does not contain NaN as longitudes and latitudes
    if (!Double.isNaN(NE.getLatitude())
            && !Double.isNaN(NE.getLongitude())
            && !Double.isNaN(SW.getLatitude())
            && !Double.isNaN(SW.getLongitude())) {
        // The borders can be used
        bordersKnownAndValid = true;
    }

    if (bordersKnownAndValid) {
        ArrayList<Report> localReports = (ArrayList<Report>) (Report.getReportsWithinBoundingBounds(NE, SW, selectedCategoryIdToBeShownOnMap).get(1));

        // Revalidate only if we have something new to show
        if (localReports.size() > 0) {
            currentMap.clearMapLayers();
            currentMap.addMarker(ParametresGeneraux.getCurrentUser().getUserIcon(),
                    new Coord(ParametresGeneraux.getCurrentUser().getCurrentUserLocation().getLatitude(),
                            ParametresGeneraux.getCurrentUser().getCurrentUserLocation().getLongitude()),
                    ParametresGeneraux.getCurrentUser().getUserNickname(), "", null);

            Image tempPlaceholder = Image.createImage(
                    reportImageWidth,
                    reportImageWidth,
                    ParametresGeneraux.accentColor);
            Graphics gr = tempPlaceholder.getGraphics();
            gr.setAntiAliased(true);
            gr.setColor(ParametresGeneraux.accentColor);
            gr.fillArc(0, 0, reportImageWidth, reportImageWidth, 0, 360);

            EncodedImage roundPlaceholder = EncodedImage.createFromImage(tempPlaceholder, true);

            // Add the report on the map
            for (Report report : localReports) {
                String photoFilenameInStorage = Report.getFilename(report.getPhotoPath())
                        + ParametresGeneraux.SUFFIX_ON_MAP_IMAGE;
                EncodedImage reportIcon = EncodedImage.createFromImage(URLImage.createToStorage(roundPlaceholder,
                        photoFilenameInStorage,
                        report.getPhotoPath(),
                        ParametresGeneraux.RESIZE_SCALE_WITH_ROUND_MASK
                ),
                        false); // we want transparency png otherwise it shows black edges

                currentMap.addMarker(reportIcon,
                        new Coord(report.getLocation().getLatitude(), report.getLocation().getLongitude()
                        ),
                        report.getCategory().getName(), "",
                        (evt) -> {
                            // Opens the detail form about this report
                            new ReportDetailsForm(theme, report, f.getClass()).show();
                        });
            }

            currentMap.setCameraPosition(new Coord(center.getLatitude(), center.getLongitude()));
            currentMap.zoom(new Coord(center.getLatitude(),
                    center.getLongitude()),
                    ParametresGeneraux.getUserZoomLevelOnMap());

            currentMap.animate();
            //f.forceRevalidate();
        }

    }

}

所以我猜模拟器中的闪烁是设备上发生的一种慢动作,尽管设备不显示占位符。

如何使标记与图像一起出现?

编辑 2017 年 3 月 8 日

在模拟器上,如果我在使用以下代码将标记添加到地图之前显示一个对话框:

Dialog.show("Photo", report.getAddress(), Dialog.TYPE_INFO, reportIcon, "OK", null);

图标在对话框中显示良好(请参见下面的屏幕截图)

然后图像出现在地图上,不再闪烁,如下所示:

但是在实际的 Android 设备上甚至不会出现对话框。

最后我不知道为什么 Dialog 使标记在模拟器上表现得像预期的那样,但在设备上却没有,所以我有点迷茫!

任何帮助都是宝贵的。

问题是 URLImage 在您将其添加为标记时可能尚未完成下载。如果您在 URLImage 完成下载之前调用 EncodedImage.createFromImage(urlImage),那么您将创建 urlImage 占位符的编码图像。

com.codename1.io.Util class 包括很多从 URL 下载图像的方法。有些是阻塞的,有些使用回调。无论哪种方式,您只需要确保在将图像添加到地图之前实际下载图像。

注意:通常这不是 URLImage 的问题 - 例如如果您要将它添加到按钮或标签。这里只是一个问题,因为MapContainer是原生的,它实际上需要在调用setMarker()时将图像数据传递给原生层。