2013-09-30 4 views
1

발리 라이브러리를 실험하고 있습니다. 항목 집합을 다운로드하여 목록보기에 넣고 각 항목에있는 원격 이미지를로드하면됩니다. 그것으로 인해 격렬한 표 목록을 구현하려고 했으므로 페이지 매김 컨트롤을 포기할 수있었습니다.android-volley의 지속적인 목록보기에서 원격 이미지를 다시로드하지 않으려면 어떻게해야하나요?

데이터를 요청하는 웹 사이트는 각각 10 개의 항목이있는 페이지에서 제공되므로 내 어댑터의 체크를 추가했습니다 .getView는 페이지의 끝 이전에 위치가 2 인 경우 (페이지의 위치 8 1, 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 하위 서브 클래스 발리슛 요청의 수정 된 버전

BaseRequest

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

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


} 

} 

에 사용합니까. 그것을 방지하는 방법에 대한 도움은 정말 감사하겠습니다.

답변

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

} 

} 
관련 문제