Подтвердить что ты не робот

Как обновить TileOverlay без мерцания?

У меня есть динамическое содержимое плитки для отображения поверх карты (в частности, погодные изображения - радар, спутник, температура и т.д.). Я использую API Карт Google для Android v2.

Проблема, с которой я сталкиваюсь, заключается в том, что, по-видимому, единственный способ обновить изображения с черепицей (т.е. когда новые данные поступают или когда кадр продвигается в анимации с временной задержкой) заключается в вызове TileOverlay.clearImageCache. К сожалению, когда я это делаю, наложение на плитки мерцает на мгновение. Это связано с тем, что clearImageCache немедленно удаляет существующие изображения с экрана, но есть задержка, прежде чем он сможет декодировать и отображать новые изображения в виде плитки.

Я использую пользовательский TileProvider, который кэширует изображения с фрагментами, а не извлекает их с сервера каждый раз. Но даже когда он подает только кешированные фрагменты (т.е. Не существует значительной задержки, наложенной моей реализацией TileProvider.getTile), все еще достаточно задержки в процессе, когда пользователь может видеть мерцание.

Кто-нибудь знает, как избежать этого мерцания? Есть ли способ удвоить буфер наложения плитки? Я попытался удвоить буфер с двумя TileOverlays, прикрепленными к карте, одна из которых невидима. Но невидимый TileOverlay не начинает получать какие-либо фрагменты из моего TileProvider - даже после вызова clearImageCache.

4b9b3361

Ответ 1

Можно ли загружать изображение будущей плитки, но имеет ли видимость значение false? Tile.setVisible(false);

Затем, когда вы хотите изменить (после того, как наступающая плитка загрузилась), установите предстоящую плитку видимой, а текущая плитка будет невидимой?

CurrentTile.setVisible(false);
NewTile.setVisible(true);

Таким образом, все изменения происходят внутри одного кадра рендеринга, и нет никакой задержки, ожидающей загрузки кэшированных изображений.

Ответ 2

Довольно хорошим решением было бы отделить загрузку и кеширование от TileProvider. Таким образом, вы можете полностью контролировать их загрузку и заменять только байты [] после загрузки всех.

Это может быть немного сложнее, потому что вам нужно позаботиться о текущей видимой области и увеличить, чтобы не загружать их все, но только те, которые будут видны.

Edit

Протестировано следующим кодом:

try {
    InputStream is = getAssets().open("tile1.jpg");
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int b = is.read();
    while (b != -1) {
        baos.write(b);
        b = is.read();
    }
    byte[] array = baos.toByteArray();
    cache = new Tile(256, 256, array);
    is = getAssets().open("tile2.jpg");
    baos = new ByteArrayOutputStream();
    b = is.read();
    while (b != -1) {
        baos.write(b);
        b = is.read();
    }
    array = baos.toByteArray();
    nextCache = new Tile(256, 256, array);
} catch (IOException ex) {
    Log.e("tag", "error reading tiles", ex);
}

tileOverlay = map.addTileOverlay(new TileOverlayOptions().tileProvider(new TileProvider() {
    @Override
    public Tile getTile(int x, int y, int zoom) {
        return cache;
    }
}));

и где-то позже:

Tile temp = cache;
cache = nextCache;
nextCache = temp;
tileOverlay.clearTileCache();

"Самый быстрый" возможный код все еще не работает.

Если вы не можете переключиться на GroundOverlay или Markers, другая идея пытается использовать плитки сторонних карт, ваши текущие погодные плитки выше и последующих плит ниже, чтобы они могли загружать и переключать их (используя zOrder) через несколько секунд.