Как обновить ImageView в окне пользовательской информации маркера [duplicate]

Возможно, вам захочется узнать, что не является CGI, и ответ - это МОДУЛЬ для вашего веб-сервера (если я предполагаю, что вы запущен Apache). И это БОЛЬШОЕ РАЗМЕЩЕНИЕ, потому что CGI нуждается и внешняя программа, нить, что бы создать экземпляр сервера приложений PERL, PHP, C, где, когда вы запускаете в качестве МОДУЛЯ эту программу, является веб-сервером (apache) per se.

Из-за всего этого в игре много проблем с производительностью, безопасностью и переносимостью. Но хорошо знать, что не является CGI первым, чтобы понять, что это такое.

4
задан Michael Julyus Christopher M. 31 March 2016 в 13:33
поделиться

1 ответ

Информационное окно - это в основном растровое изображение, захваченное из просмотров, которые вы заполняете. В результате изменения этих просмотров & mdash; такие как Picasso, асинхронно обновляющие ImageView & mdash; не будет обновлять информационное окно.

Одно из решений, которое работает, - вызвать showInfoWindow() на Marker после того, как Picasso получил и закрепил изображение. Например, этот пример приложения использует Picasso для заполнения информационных окон и использует Picasso Callback для вызова showInfoWindow():

/***
  Copyright (c) 2013-2014 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    https://commonsware.com/Android
 */

package com.commonsware.android.mapsv2.imagepopups;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.HashMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.model.Marker;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

class PopupAdapter implements InfoWindowAdapter {
  private View popup=null;
  private LayoutInflater inflater=null;
  private HashMap<String, Uri> images=null;
  private Context ctxt=null;
  private int iconWidth=-1;
  private int iconHeight=-1;
  private Marker lastMarker=null;

  PopupAdapter(Context ctxt, LayoutInflater inflater,
               HashMap<String, Uri> images) {
    this.ctxt=ctxt;
    this.inflater=inflater;
    this.images=images;

    iconWidth=
        ctxt.getResources().getDimensionPixelSize(R.dimen.icon_width);
    iconHeight=
        ctxt.getResources().getDimensionPixelSize(R.dimen.icon_height);
  }

  @Override
  public View getInfoWindow(Marker marker) {
    return(null);
  }

  @SuppressLint("InflateParams")
  @Override
  public View getInfoContents(Marker marker) {
    if (popup == null) {
      popup=inflater.inflate(R.layout.popup, null);
    }

    if (lastMarker == null
        || !lastMarker.getId().equals(marker.getId())) {
      lastMarker=marker;

      TextView tv=(TextView)popup.findViewById(R.id.title);

      tv.setText(marker.getTitle());
      tv=(TextView)popup.findViewById(R.id.snippet);
      tv.setText(marker.getSnippet());

      Uri image=images.get(marker.getId());
      ImageView icon=(ImageView)popup.findViewById(R.id.icon);

      if (image == null) {
        icon.setVisibility(View.GONE);
      }
      else {
        Picasso.with(ctxt).load(image).resize(iconWidth, iconHeight)
               .centerCrop().noFade()
               .placeholder(R.drawable.placeholder)
               .into(icon, new MarkerCallback(marker));
      }
    }

    return(popup);
  }

  static class MarkerCallback implements Callback {
    Marker marker=null;

    MarkerCallback(Marker marker) {
      this.marker=marker;
    }

    @Override
    public void onError() {
      Log.e(getClass().getSimpleName(), "Error loading thumbnail!");
    }

    @Override
    public void onSuccess() {
      if (marker != null && marker.isInfoWindowShown()) {
        marker.showInfoWindow();
      }
    }
  }
}

В принципе, если Picasso получает изображение, информационное окно все еще открыто для ассоциированного Marker, я вызываю showInfoWindow(). Визуальный эффект похож на обычное поведение Пикассо: местозаполнитель, за которым следует реальное изображение, заменяющее местозаполнитель.

12
ответ дан CommonsWare 19 August 2018 в 07:04
поделиться
  • 1
    Можете ли вы дать мне код? Какой код мне нужно изменить или добавить в мой код? – Michael Julyus Christopher M. 31 March 2016 в 13:58
  • 2
    Отличное объяснение и пример. – AL. 31 March 2016 в 23:33
  • 3
    Благодарю. Теперь он работает для меня при использовании Picasso callback – Michael Julyus Christopher M. 1 April 2016 в 03:04
  • 4
    Я не знаю почему, но он работает только в том случае, если я не использую .resize(iconWidth, iconHeight).centerCrop().noFade() и .fit(). – Jaec 11 May 2017 в 06:33
Другие вопросы по тегам:

Похожие вопросы: