首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免使用android-volley在连续列表视图中重新加载远程图像?

如何避免使用android-volley在连续列表视图中重新加载远程图像?
EN

Stack Overflow用户
提问于 2013-09-30 08:08:47
回答 1查看 970关注 0票数 1

我在试验截击库。我下载了一组项目,将它们放到列表视图中,并加载每个项目都可以的远程图像。受此鼓舞,我尝试实现一个连续的列表视图,这样我就可以放弃分页控制。

我请求的网站提供的数据包含10个条目,因此我在adapter.getView上添加了一个检查,以便如果在页面结束前位置为2 (第1页的位置8,第2页的位置为18 ),它应该加载一个新页面并将新项目追加到列表的末尾。这很管用,但这种行为与我所期望的不一样。

第一页加载ok,图像加载需要几秒钟时间,但没关系。然后,当我向下滚动时,当它加载新页面时,所有已经显示的图像(已经显示的)都会显示出来,尽管它们与新页面一起再次显示。这是,它加载确定的前10张图片,然后它的“打嗝”,使他们失去理智,他们再次出现与接下来的10张图片。数据,但是,加载ok,不解散或任何类似的东西。

这是我的ArrayAdapter

代码语言:javascript
复制
public class ItemAdapter extends ArrayAdapter<Item> implements Listener<JSONObject>, ErrorListener{

private static final String TAG = VolleyTestApp.LOGTAG;

private final Context mCtx;
private final ArrayList<Item> items;

//private int elegido = -1;
ItemsViewHolder viewHolder;

/**********************************/
private int pageSize = 0;
private int currentPage = 0;
private boolean mLoading = false;
private RequestQueue rq;
private ItemsListRequestParameter params;

public ItemAdapter(Context context, int resource,
        List<Item> objects) {
    super(context, resource, 
            objects);
    mCtx = context;
    items = (ArrayList<Item>) objects;
    rq = SingletonRequestQueue.getInstance(mCtx);
}

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;

    LayoutInflater vi = ((Activity) mCtx).getLayoutInflater();

    v = vi.inflate(R.layout.items_list_item, null);
    viewHolder = new ItemsViewHolder(v);
    Log.d(TAG, "Adapter viewholder creado " );

    v.setTag(viewHolder);
    viewHolder = (ItemsViewHolder) v.getTag();


    Log.d(TAG, "Adapter posición: " + position);

    if(viewHolder != null){
        if (items.size() > 0){
            Log.d(TAG, "Adapter tamaño lista: " + getCount());
            Item t = items.get(position);
            Log.d(TAG, "Adapter devolviendo item: " + items.get(position).getItemName());
            String foto = t.getItemPicUrl();
            if (foto == null || foto.equalsIgnoreCase("")){
                viewHolder.itemPic.setImageResource(R.drawable.img_default_item_thumbnail);
            }else{
                Log.d(TAG, "Adapter devolviendo item foto: " + foto);
                int cacheSize = getCacheSize();
                Log.d(TAG, "Adapter cacheSize: " + cacheSize);
                BitmapLruImageCache cache = new BitmapLruImageCache(cacheSize);
                ImageLoader imgLoader = 
                        new ImageLoader(SingletonRequestQueue.getInstance(mCtx),
                                cache);

                viewHolder.itemPic.setImageUrl(foto, imgLoader);
            }
            viewHolder.itemName.setText(t.getItemName());
            viewHolder.itemData1.setText(t.getData1());

        }
    }else{
        Log.d(TAG, "Adapter viewHolder null: " );
    }
    /**************************************************/
    Log.d(TAG, "Adapter.getView posición: " + position + "; pageSize: " + pageSize + "; currentPage: " + currentPage);
    if (position +2 == (this.pageSize * (this.currentPage +1)  )&& !mLoading){
        Log.d(TAG, "Adapter.getView pidiendo nuevos datos");
        if(this.params == null){
            Log.w(TAG, "Adapter.getView params null " );
        }else{
            Log.w(TAG, "Adapter.getView nueva carga" );
            this.params.nextPage();
            this.loadData(this.params, pageSize);
        }
    }

    return v;
}


public int getCacheSize() {
    final DisplayMetrics displayMetrics = mCtx.getResources().getDisplayMetrics();
    final int screenWidth = displayMetrics.widthPixels;
    final int screenHeight = displayMetrics.heightPixels;
    final int screenBytes = screenWidth * screenHeight * 4; // 4 bytes per pixel

    return screenBytes * 3;
}




@Override
public void add(Item object) {
    items.add(object);
    Log.d(TAG, "Item añadida a adapter: " + object.getItemName());
}
@Override
public void clear() {
    //super.clear();
    items.clear();
}
@Override
public int getCount() {
    return items.size();
}



static class ItemsViewHolder{
    TextView        itemName;
    TextView        itemData1;
    NetworkImageView itemPic;

    LinearLayout container;

    public ItemsViewHolder(View v){
        this.itemName = (TextView) v.findViewById(R.id.lti_nombre_item);
        this.itemData1 = (TextView) v.findViewById(R.id.lti_datos_item1);
        this.itemPic = (NetworkImageView) v.findViewById(R.id.tli_r_img);
        this.container = (LinearLayout) v.findViewById(R.id.lti_container);
    }

}



public void loadData(ItemsListRequestParameter params, int pageSize){
    mLoading = true;
    ItemListRequest jr = new ItemListRequest(params, this, this);
    this.pageSize = pageSize;
    this.params = params;
    this.rq.add(jr);    
}



@Override
public void onErrorResponse(VolleyError error) {
    Log.d(TAG, "Adapter.onErrorResponse request con error");
    mLoading = false;
    // TODO meter elemento con mensaje error
    Log.i(TAG, "Adapter.onErrorResponse request respondida " + error.getMessage());

}

@Override
public void onResponse(JSONObject response) {
    Log.d(TAG, "Adapter.onResponse request respondida " + response.toString());
    mLoading = false;
    Response tr = ResponseParser.parseUltimasItemsJSONresponse(response);
    if (tr.getResponseCode().equalsIgnoreCase("000")){
        DaoList tdl = (DaoList) tr.getResponseInfo(); 
        this.currentPage = tdl.getCurrentPage();
        Log.d(TAG, "Adapter.onResponse  currentPage: " + currentPage);
        Iterator<Dao> it = tdl.iterator();
        //tta.clear();
        while (it.hasNext()){
            Item t = (Item) it.next();
            this.add(t);
        }
        this.notifyDataSetChanged();
    }

}

}

我的ItemListRequest子类是修改后的volley请求版本。

BaseRequest

代码语言:javascript
复制
public class BaseRequest extends Request<JSONObject>{


private Listener<JSONObject> mListener;

public BaseRequest(int method, 
        String url,
        Listener<JSONObject> successListener,
        ErrorListener errorListener) {

    super(method,url,errorListener);
    this.mListener = successListener;

}

/**
 * transform NetworkResponse into Response<JSONObject>
 */
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
        String jsonString =
            new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        return Response.success(new JSONObject(jsonString),
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JSONException je) {
        return Response.error(new ParseError(je));
    }
}


/**
 * Here we send the response to the successListener
 */
@Override
protected void deliverResponse(JSONObject response) {
    this.mListener.onResponse(response);
}

}

PostRequest

代码语言:javascript
复制
public class PostRequest extends BaseRequest {

private Map<String, String> mParams;
private static int method = Method.POST;
public PostRequest(ItemsListRequestParameter params,
        String url, Listener<JSONObject> successListener,
        ErrorListener errorListener) {

    super(method, url, successListener, errorListener);
    this.mParams = params.getMappedParams();
}

/**
 * Override getParams so that it returns our POST params
 */
@Override
protected Map<String, String> getParams() throws AuthFailureError { 
    return mParams;
}

}

和ItemListRequest,我在适配器中使用的实际请求

代码语言:javascript
复制
public class ItemListRequest extends PostRequest{

public ItemListRequest(TapasListRequestParameter params,
        Listener<JSONObject> successListener,
        ErrorListener errorListener) {

    super( params, RequestData.SEARCH_TAPAS_LIST_URL,successListener, errorListener);

    this.setShouldCache(Boolean.TRUE);


}

}

我真的不明白这些图像重新加载的原因。任何关于如何预防它的帮助都将是非常感谢的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-01 16:56:10

因此,我得到了一些外部帮助,并找到了答案:在每次getView执行时,我都在重新创建图像缓存。诀窍是移出缓存对象的创建。最好的主意是一个单例,但是为了这个实验,我将把它放在Adapter类上:

代码语言:javascript
复制
public class ItemAdapter extends ArrayAdapter<Item> implements Listener<JSONObject>, ErrorListener{

private static final String TAG = VolleyTestApp.LOGTAG;

private final Context mCtx;
private final ArrayList<Item> items;

//private int elegido = -1;
ItemsViewHolder viewHolder;

/**********************************/
private int pageSize = 0;
private int currentPage = 0;
private boolean mLoading = false;
private RequestQueue rq;
private ItemsListRequestParameter params;
// add the cache object as a class attribute
private BitmapLruImageCache cache;

public ItemAdapter(Context context, int resource,
        List<Item> objects) {
    super(context, resource, 
            objects);
    mCtx = context;
    items = (ArrayList<Item>) objects;
    rq = SingletonRequestQueue.getInstance(mCtx);

    // instantiate the cache object on the constructor
    int cacheSize = getCacheSize();
    BitmapLruImageCache cache = new BitmapLruImageCache(cacheSize);

}

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;

    LayoutInflater vi = ((Activity) mCtx).getLayoutInflater();

    v = vi.inflate(R.layout.items_list_item, null);
    viewHolder = new ItemsViewHolder(v);
    Log.d(TAG, "Adapter viewholder creado " );

    v.setTag(viewHolder);
    viewHolder = (ItemsViewHolder) v.getTag();

    Log.d(TAG, "Adapter posición: " + position);

    if(viewHolder != null){
        if (items.size() > 0){
            Log.d(TAG, "Adapter tamaño lista: " + getCount());
            Item t = items.get(position);
            Log.d(TAG, "Adapter devolviendo item: " + items.get(position).getItemName());
            String foto = t.getItemPicUrl();
            if (foto == null || foto.equalsIgnoreCase("")){
                viewHolder.itemPic.setImageResource(R.drawable.img_default_item_thumbnail);
            }else{

                ImageLoader imgLoader = 
                        new ImageLoader(SingletonRequestQueue.getInstance(mCtx),
                                cache);

                viewHolder.itemPic.setImageUrl(foto, imgLoader);
            }
            viewHolder.itemName.setText(t.getItemName());
            viewHolder.itemData1.setText(t.getData1());

        }
    }else{
        Log.d(TAG, "Adapter viewHolder null: " );
    }
    /**************************************************/
    Log.d(TAG, "Adapter.getView posición: " + position + "; pageSize: " + pageSize + "; currentPage: " + currentPage);
    if (position +2 == (this.pageSize * (this.currentPage +1)  )&& !mLoading){
        Log.d(TAG, "Adapter.getView pidiendo nuevos datos");
        if(this.params == null){
            Log.w(TAG, "Adapter.getView params null " );
        }else{
            Log.w(TAG, "Adapter.getView nueva carga" );
            this.params.nextPage();
            this.loadData(this.params, pageSize);
        }
    }

    return v;
}


public int getCacheSize() {
    final DisplayMetrics displayMetrics = mCtx.getResources().getDisplayMetrics();
    final int screenWidth = displayMetrics.widthPixels;
    final int screenHeight = displayMetrics.heightPixels;
    final int screenBytes = screenWidth * screenHeight * 4; // 4 bytes per pixel

    return screenBytes * 3;
}




@Override
public void add(Item object) {
    items.add(object);
    Log.d(TAG, "Item añadida a adapter: " + object.getItemName());
}
@Override
public void clear() {
    //super.clear();
    items.clear();
}
@Override
public int getCount() {
    return items.size();
}



static class ItemsViewHolder{
    TextView        itemName;
    TextView        itemData1;
    NetworkImageView itemPic;

    LinearLayout container;

    public ItemsViewHolder(View v){
        this.itemName = (TextView) v.findViewById(R.id.lti_nombre_item);
        this.itemData1 = (TextView) v.findViewById(R.id.lti_datos_item1);
        this.itemPic = (NetworkImageView) v.findViewById(R.id.tli_r_img);
        this.container = (LinearLayout) v.findViewById(R.id.lti_container);
    }

}



public void loadData(ItemsListRequestParameter params, int pageSize){
    mLoading = true;
    ItemListRequest jr = new ItemListRequest(params, this, this);
    this.pageSize = pageSize;
    this.params = params;
    this.rq.add(jr);    
}



@Override
public void onErrorResponse(VolleyError error) {
    Log.d(TAG, "Adapter.onErrorResponse request con error");
    mLoading = false;
    // TODO meter elemento con mensaje error
    Log.i(TAG, "Adapter.onErrorResponse request respondida " + error.getMessage());

}

@Override
public void onResponse(JSONObject response) {
    Log.d(TAG, "Adapter.onResponse request respondida " + response.toString());
    mLoading = false;
    Response tr = ResponseParser.parseUltimasItemsJSONresponse(response);
    if (tr.getResponseCode().equalsIgnoreCase("000")){
        DaoList tdl = (DaoList) tr.getResponseInfo(); 
        this.currentPage = tdl.getCurrentPage();
        Log.d(TAG, "Adapter.onResponse  currentPage: " + currentPage);
        Iterator<Dao> it = tdl.iterator();
        //tta.clear();
        while (it.hasNext()){
            Item t = (Item) it.next();
            this.add(t);
        }
        this.notifyDataSetChanged();
    }

}

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19089307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档