Android:一旦图像通过毕加索下载,如何重新加载自定义标记? [英] Android : how to reload custom markers once the image is downloaded via Picasso?

查看:89
本文介绍了Android:一旦图像通过毕加索下载,如何重新加载自定义标记?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将用户头像动态加载为自定义标记。我将我的代码放在google maps utils demo上,但不知何故,它只加载一个图像,其他所有图像都是空的:





以下是我的代码:

  public class MapsActivity extends FragmentActivity implements ClusterManager.OnClusterItemClickListener< ModelUser>,ClusterManager.OnClusterItemInfoWindowClickListener< ModelUser> {

私人ClusterManager< ModelUser> mClusterManager;
私有GoogleMap mMap; //如果Google Play服务APK不可用,则可能为空。
私人QueryAPI查询=新的QueryAPI();
私人列表< ModelUser> users = new ArrayList< ModelUser>();
ImageLoader imageLoader = AppController.getInstance()。getImageLoader();

// UI
NetworkImageView avatarImageView;
TextView名称;
TextView信息;
TextView距离;
RelativeLayout detailView;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);

setUpMapIfNeeded();

detailView =(RelativeLayout)findViewById(R.id.detailView);
avatarImageView =(NetworkImageView)findViewById(R.id.imageView);
name =(TextView)findViewById(R.id.name);
infos =(TextView)findViewById(R.id.info);
distance =(TextView)findViewById(R.id.distance);

$ b query.nearUsers(new QueryAPI.ApiResponse< List< ModelUser>>(){
@Override
public void onCompletion(List< ModelUser> result) {

users = result;

setUpClusterer();
}
}); ();

}

@Override
保护无效onResume(){
super.onResume();
setUpMapIfNeeded();
}


private void setUpMap(){
mMap.setMyLocationEnabled(true);
}

private void setUpClusterer(){

//定位地图。
getMap()。moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(46.155115,2.473060),5));

//用上下文和地图初始化管理器。
//(Activity扩展了上下文,所以我们可以在构造函数中传递'this'。)
mClusterManager = new ClusterManager< ModelUser>(this,getMap());

//将映射的侦听器指向集群
//管理器实现的侦听器。
getMap()。setOnCameraChangeListener(mClusterManager);
getMap()。setOnMarkerClickListener(mClusterManager);
mClusterManager.setRenderer(new PersonRenderer());
mClusterManager.setOnClusterItemClickListener(this);
mClusterManager.setOnClusterItemInfoWindowClickListener(this);

//将群集项(标记)添加到群集管理器。
addItems();


private void addItems(){

for(int i = 0; i< users.size(); i ++){

ModelUser user = users.get(i);

mClusterManager.addItem(user);



$ b保护GoogleMap getMap(){
setUpMapIfNeeded();
return mMap;
}

@Override
public boolean onClusterItemClick(ModelUser item){

Log.d(User clicked:,item.getName() );
avatarImageView.setImageUrl(item.getAvatar_url(),imageLoader);
name.setText(item.getName());
infos.setText(item.getAge());
double d = Double.parseDouble(item.getDistance());
distance.setText(String.format(%。1f,d)+Km);
detailView.setVisibility(View.VISIBLE);
返回false;


@Override
public void onClusterItemInfoWindowClick(ModelUser item){

Log.d(User Window clicked:,item.getName ));
}

/ **
*在标记内绘制轮廓照片(使用IconGenerator)。
*群集中有多个人时,绘制多张照片(使用MultiDrawable)。
* /
私人类PersonRenderer扩展DefaultClusterRenderer< ModelUser> {
private final IconGenerator mIconGenerator = new IconGenerator(getApplicationContext());
private final UICircularImage mImageView;
// private final int mDimension;

public PersonRenderer(){
super(getApplicationContext(),getMap(),mClusterManager);

View profile = getLayoutInflater()。inflate(R.layout.map_marker_item,null);
mIconGenerator.setContentView(profile);
mImageView =(UICircularImage)profile.findViewById(R.id.avatarImageView);

}

@Override
保护void onBeforeClusterItemRendered(ModelUser user,MarkerOptions markerOptions){
//绘制一个人。
//设置信息窗口显示他们的名字。
// mImageView.setImageUrl(user.getAvatar_url(),imageLoader);
Picasso.with(getApplicationContext())
.load(user.getAvatar_url())
.noFade()
.into(mImageView,new com.squareup.picasso.Callback (){
@Override
public void onSuccess(){

//重新加载标记这里

}

@Override
public void onError(){
$ b}
});
位图图标= mIconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon))。title(user.getName());
}

}

任何想法为什么?



编辑:我意识到有时它会加载所有图像,我认为问题来自异步任务。所以我现在的问题是:如果我实现回调以知道毕加索何时加载图像,我该如何重新加载这个特定标记? 解决方案我们将从毕加索加载原始位图,然后将其传递给表示当前用户的标记。

getApplicationContext())
.load(user.getAvatar_url())
.into(new com.squareup.picasso.Target(){
@Override
public void onBitmapLoaded(Bitmap位图,Picasso.LoadedFrom from){
//让我们为这个用户找到标记
Marker markerToChange = null;
for(Marker marker:mClusterManager.getMarkerCollection()。getMarkers()){
if(marker.getPosition()。equals(user.getPosition())){
markerToChange = marker;
break;
}
}
//如果找到 - 更改图标
if(markerToChange!= null){
markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));

$ b @Override
public void onBitmapFailed(Drawable errorDrawable){
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});

我也有一些毕加索的麻烦。所以,我推荐使用Glide

  compile'c​​om.github.bumptech.glide:glide:3.5.2'



Glide.with(getApplicationContext())。
load(user.getAvatar_url())
.asBitmap()
.fitCenter()
.into(new SimpleTarget< Bitmap>(){
@Override
public void onResourceReady(位图位图,GlideAnimation< ;?超级位图> glideAnimation){
//让我们为这个用户找到标记
Marker markerToChange = null;
for(Marker marker:mClusterManager .getMarkerCollection()。getMarkers()){
if(marker.getPosition()。equals(user.getPosition())){
markerToChange = marker;
break;
}
}
// if if found - change icon
if(markerToChange!= null){
markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
}
}
});


I'm trying to load dynamically users avatars as custom markers. I based my code on the google maps utils demo, but somehow it doesn't work, it loads only one image and all the others are empty:

Here is my code:

public class MapsActivity extends FragmentActivity implements ClusterManager.OnClusterItemClickListener<ModelUser>, ClusterManager.OnClusterItemInfoWindowClickListener<ModelUser> {

    private ClusterManager<ModelUser> mClusterManager;
    private GoogleMap mMap; // Might be null if Google Play services APK is not available.
    private QueryAPI query = new QueryAPI();
    private List<ModelUser> users = new ArrayList<ModelUser>();
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    //UI
    NetworkImageView avatarImageView;
    TextView name;
    TextView infos;
    TextView distance;
    RelativeLayout detailView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        setUpMapIfNeeded();

        detailView = (RelativeLayout) findViewById(R.id.detailView);
        avatarImageView = (NetworkImageView) findViewById(R.id.imageView);
        name = (TextView) findViewById(R.id.name);
        infos = (TextView) findViewById(R.id.info);
        distance = (TextView) findViewById(R.id.distance);


        query.nearUsers(new QueryAPI.ApiResponse<List<ModelUser>>() {
            @Override
            public void onCompletion(List<ModelUser> result) {

                users = result;

                setUpClusterer();
            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }


    private void setUpMap() {
        mMap.setMyLocationEnabled(true);
    }

    private void setUpClusterer() {

        // Position the map.
        getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(46.155115, 2.473060), 5));

        // Initialize the manager with the context and the map.
        // (Activity extends context, so we can pass 'this' in the constructor.)
        mClusterManager = new ClusterManager<ModelUser>(this, getMap());

        // Point the map's listeners at the listeners implemented by the cluster
        // manager.
        getMap().setOnCameraChangeListener(mClusterManager);
        getMap().setOnMarkerClickListener(mClusterManager);
        mClusterManager.setRenderer(new PersonRenderer());
        mClusterManager.setOnClusterItemClickListener(this);
        mClusterManager.setOnClusterItemInfoWindowClickListener(this);

        // Add cluster items (markers) to the cluster manager.
        addItems();
    }

    private void addItems() {

        for (int i = 0; i < users.size(); i++) {

            ModelUser user = users.get(i);

            mClusterManager.addItem(user);
        }

    }

    protected GoogleMap getMap() {
        setUpMapIfNeeded();
        return mMap;
    }

    @Override
    public boolean onClusterItemClick(ModelUser item) {

        Log.d("User clicked:", item.getName());
        avatarImageView.setImageUrl(item.getAvatar_url(), imageLoader);
        name.setText(item.getName());
        infos.setText(item.getAge());
        double d = Double.parseDouble(item.getDistance());
        distance.setText( String.format("%.1f", d) + "Km");
        detailView.setVisibility(View.VISIBLE);
        return false;
    }

    @Override
    public void onClusterItemInfoWindowClick(ModelUser item) {

        Log.d("User Window clicked:", item.getName());
    }

    /**
     * Draws profile photos inside markers (using IconGenerator).
     * When there are multiple people in the cluster, draw multiple photos (using MultiDrawable).
     */
    private class PersonRenderer extends DefaultClusterRenderer<ModelUser> {
        private final IconGenerator mIconGenerator = new IconGenerator(getApplicationContext());
        private final UICircularImage mImageView;
        //private final int mDimension;

        public PersonRenderer() {
            super(getApplicationContext(), getMap(), mClusterManager);

            View profile = getLayoutInflater().inflate(R.layout.map_marker_item, null);
            mIconGenerator.setContentView(profile);
            mImageView = (UICircularImage) profile.findViewById(R.id.avatarImageView);

        }

        @Override
        protected void onBeforeClusterItemRendered(ModelUser user, MarkerOptions markerOptions) {
            // Draw a single person.
            // Set the info window to show their name.
           // mImageView.setImageUrl(user.getAvatar_url(), imageLoader);
            Picasso.with(getApplicationContext())
                .load(user.getAvatar_url())
                .noFade()
                .into(mImageView, new com.squareup.picasso.Callback() {
                    @Override
                    public void onSuccess() {

                       //reload the marker HERE

                    }

                    @Override
                    public void onError() {

                    }
                });
            Bitmap icon = mIconGenerator.makeIcon();
            markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).title(user.getName());
        }

    }

Any idea why?

EDIT: I realized that sometimes it does load all the images, I think the problem comes from the async task. So my question is now: if I implement a callback to know when Picasso has finished to load the image, how can I reload this specific marker?

解决方案

We'll load raw bitmap from Picasso and then pass it to marker representing current user

Picasso.with(getApplicationContext())
        .load(user.getAvatar_url())
        .into(new com.squareup.picasso.Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                // let's find marker for this user
                Marker markerToChange = null;
                for (Marker marker : mClusterManager.getMarkerCollection().getMarkers()) {
                    if (marker.getPosition().equals(user.getPosition())) {
                        markerToChange = marker;
                        break;
                    }
                }
                // if found - change icon
                if (markerToChange != null) {
                    markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
                }
            }
            @Override
            public void onBitmapFailed(Drawable errorDrawable) {
            }
            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
            }
        });

I have some troubles with Picasso too. So, i recommend to use Glide

compile 'com.github.bumptech.glide:glide:3.5.2'



Glide.with(getApplicationContext()).
            load(user.getAvatar_url())
            .asBitmap()
            .fitCenter()
            .into(new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
                    // let's find marker for this user
                    Marker markerToChange = null;
                    for (Marker marker : mClusterManager.getMarkerCollection().getMarkers()) {
                        if (marker.getPosition().equals(user.getPosition())) {
                            markerToChange = marker;
                            break;
                        }
                    }
                    // if found - change icon
                    if (markerToChange != null) {
                        markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
                    }
                }
            });

这篇关于Android:一旦图像通过毕加索下载,如何重新加载自定义标记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆