1

我正在尝试使用 volley 库。我得到它来下载一组项目,将它们放入列表视图并加载每个项目都可以的远程图像。受此鼓舞,我尝试实现一个连续的列表视图,这样我就可以放弃分页控件。

我要从中请求数据的网站在页面中提供数据,每个页面有 10 个项目,因此我在我的 adapter.getView 上添加了一个检查,以便在页面结束之前位置为 2(第 1 页的位置 8,第 18 页的位置第 2 页等),它应该加载一个新页面并将新项目附加到列表的末尾。它有效,但行为不是我所期望的。

第一页加载正常,图像加载需要几秒钟,但没关系。然后,当我向下滚动时,当它加载新页面时,所有已经显示的图像都消失了,尽管它们与新的图像一起再次出现。也就是说,它加载好的前 10 张图片,然后“打嗝”使它们消失,然后它们与接下来的 10 张图片一起重新出现。但是,数据加载正常并且不会消失或类似的东西。

这是我的 ArrayAdapter

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 Request 的修改版本

基本请求

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);
}

}

后请求

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,我在适配器中使用的实际请求

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);


}

}

我真的不明白图像重新加载背后的原因。任何有关如何防止它的帮助将不胜感激。

4

1 回答 1

0

所以,我得到了一些外部帮助并弄清楚了:我在每次执行 getView 时都重新创建了图像缓存。诀窍是移出缓存对象的创建。最好的主意是 Singleton,但为了这个实验,我将把它留在 Adapter 类上:

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();
    }

}

}
于 2013-10-01T16:56:10.907 回答