我Activity
了GoogleMap
,我向服务器发送请求,解析JSON响应并添加Markers
,使用毕加索加载图标。
问题
问题是接下来:当我关闭应用程序并再次打开它时,数据也会加载(url 加载也很好),Markers
被添加到GoogleMap
上,但它们有默认图标,毕加索不会加载新图标(未调用 BitmapLoaded()。当我完成Activity
并重新启动它(没有关闭应用程序)时,新标记的图标也会加载。
我对毕加索目标的实现:
public class PicassoMarker implements Target {
private static final String TAG = "PicassoMarker";
private Marker marker;
private LoadingCallBacks loadingCallBacks;
public PicassoMarker(Marker marker) {
this.marker = marker;
}
public PicassoMarker(Marker marker, LoadingCallBacks loadingCallBacks) {
this.marker = marker;
this.loadingCallBacks = loadingCallBacks;
}
@Override
public int hashCode() {
return marker.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof PicassoMarker) {
Marker marker = ((PicassoMarker) o).marker;
return this.marker.equals(marker);
} else {
return false;
}
}
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
Log.d(TAG, "onBitmapLoaded() -> " +
"nBitmap:" +
"ntwidth: " + bitmap.getWidth() +
"ntheight: " + bitmap.getHeight() /*+
"nCanvas:" +
"ntwidth: " + resultBitmap.getWidth() +
"ntheight: " + resultBitmap.getHeight()*/
);
if (loadingCallBacks != null) {
loadingCallBacks.onLoaded(bitmap);
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.e(TAG, "onBitmapFailed()");
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d(TAG, "onPrepareLoad()");
}
public void setLoadingCallBacks(LoadingCallBacks loadingCallBacks) {
this.loadingCallBacks = loadingCallBacks;
}
public interface LoadingCallBacks {
void onLoaded(Bitmap bitmap);
}
}
以及我发送请求和添加Markers
AsyncTask
:
new AsyncTask<String, Void, ArrayList<MarkerDataModel>>() {
private ArrayList<MarkerDataModel> markerDataModels = new ArrayList<>();
@Override
protected void onPreExecute() {
}
@Override
protected ArrayList<MarkerDataModel> doInBackground(String... params) {
// Parsing JSON ...
return markerDataModels;
}
@Override
protected void onPostExecute(ArrayList<MarkerDataModel> markerDataModels) {
if (markerDataModels != null && markerDataModels.size() != 0) {
MarkerDataModel markerDataModel;
for (int i = 0; i < markerDataModels.size(); i++) {
markerDataModel = markerDataModels.get(i);
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(markerDataModel.getLat(), markerDataModel.getLng()))
.title(markerDataModel.getLabel()));
PicassoMarker picassoMarker picassoMarker = new PicassoMarker(marker);
Picasso.
with(activityContext)
.load(markerDataModel.getIcon())
//.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
//.networkPolicy(NetworkPolicy.NO_CACHE)
.into(picassoMarker);
}
}
}
}.execute("http://example.com");
解决方案
我已经解决了问题,使用滑翔。
以下是从网络加载Markers'
数据并使用 Glide 设置新图标的示例代码:
new AsyncTask<String, Void, ArrayList<MarkerDataModel>>() {
@Override
protected void onPreExecute() {
...
}
@Override
protected ArrayList<MarkerDataModel> doInBackground(String... params) {
ArrayList<MarkerDataModel> markerDataModels = new ArrayList<>();
Send request and parse response...
return markerDataModels;
}
@Override
protected void onPostExecute(ArrayList<MarkerDataModel> markerDataModels) {
if (markerDataModels != null && markerDataModels.size() != 0) {
for (int i = 0; i < markerDataModels.size(); i++) {
MarkerDataModel markerDataModel = markerDataModels.get(i);
final Marker marker = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(markerDataModel.getLat(), markerDataModel.getLng()))
.title(markerDataModel.getLabel()));
// Getting icon's URL from DataModel and loading icon
Glide
.with(activityContext)
.load(markerDataModel.getIcon())
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// Setting new icon for Marker
marker.setIcon(BitmapDescriptorFactory.fromBitmap(resource));
}
});
}
}
}
}.execute(...);
MarkerDataModel
是用于存储Marker's
数据的简单类:
public class MarkerDataModel {
public MarkerDataModel() {
}
private final String TAG = "MarkerDataModel";
public static final int TYPE_PRIMARY = 1;
public static final int TYPE_PEOPLE = 2;
private int type;
private int id;
private double lat;
private double lng;
private Marker marker;
/**
* TYPE_PRIMARY
**/
private String icon;
private String label;
private String nameShort;
private String nameFull;
private String phone;
private String information;
private String website;
private String sliderImages;
/**
* TYPE_PEOPLE
**/
private String photoUrl;
private String uniqueId;
private String registerTime;
public MarkerDataModel(int type,
int id,
double lat,
double lng,
String icon,
String label,
String nameShort,
String nameFull,
String phone,
String information,
String website,
String sliderImages) {
this.type = type;
this.id = id;
this.lat = lat;
this.lng = lng;
this.icon = icon;
this.label = label;
this.nameShort = nameShort;
this.nameFull = nameFull;
this.phone = phone;
this.information = information;
this.website = website;
this.sliderImages = sliderImages;
}
public MarkerDataModel(int type,
int id,
double lat,
double lng,
String photoUrl,
String uniqueId,
String registerTime) {
this.type = type;
this.lat = lat;
this.lng = lng;
this.photoUrl = photoUrl;
this.uniqueId = uniqueId;
this.registerTime = registerTime;
}
/**
* Getters
*/
public int getType() {
return type;
}
@Nullable
public Marker getMarker() {
return marker;
}
public int getId() {
return id;
}
public double getLat() {
return lat;
}
public double getLng() {
return lng;
}
/**
* TYPE_PRIMARY
**/
public String getIcon() {
return icon;
}
public String getInformation() {
return information;
}
public String getLabel() {
return label;
}
public String getNameFull() {
return nameFull;
}
public String getNameShort() {
return nameShort;
}
public String getPhone() {
return phone;
}
public String getSliderImages() {
return sliderImages;
}
public String getWebsite() {
return website;
}
/**
* TYPE_PEOPLE
**/
public String getPhotoUrl() {
return photoUrl;
}
public String getUniqueId() {
return uniqueId;
}
public String getRegisterTime() {
return registerTime;
}
@Nullable
public LatLng getLatLng() {
try {
return new LatLng(lat, lng);
} catch (Exception ex) {
Log.e(TAG, "getLatLng() -> ", ex);
return null;
}
}
/**
* Setters
*/
public void setMarker(Marker marker) {
this.marker = marker;
}
}
好处
在TYPE_PRIMARY
和TYPE_PEOPLE
之间切换,您可以捕获点击Marker
的类型,如下所示:
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
MarkerDataModel markerDataModel = markerAllHashMap.get(marker);
int type;
try {
Log.d(TAG, "onMarkerClick() -> " + markerDataModel.getType());
} catch (Exception ex) {
Log.e(TAG, "onMarkerClick() -> ", ex);
}
try {
type = markerDataModel.getType();
} catch (Exception ex) {
type = -1;
}
switch (type) {
case MarkerDataModel.TYPE_PRIMARY: {
// Do something for TYPE_PRIMARY Marker
break;
}
case MarkerDataModel.TYPE_PEOPLE: {
// Do something for TYPE_PEOPLE Marker (e.g. show user's info)
break;
}
default: {
// Type == -1
marker.showInfoWindow();
break;
}
}
// Animate to center
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(marker.getPosition())
.zoom(18)
.build()));
return true;
}
});