2012-09-02 51 views
0

我正在一個應用程序中,我有一個listview,這是通過ArrayAdapter填充。除了現在變得相當令人惱火的問題之外,所有的事情都很好。列表視圖當我點擊時自動更改位置?

我的列表視圖具有infalted自定義佈局包含圖像,然後文本。問題在於圖像部分。當我在列表中點擊列表時,列表中的圖像將在那裏交換位置。比如說,例如與第一個單元格相關的圖像會轉到第三個單元格,反之亦然,等等。它只發生在圖片上。文本仍然處於它的位置。我不知道問題是什麼。請幫我解決這個嚴重的問題。

以下是我的適配器代碼:

public class PListAdapter extends ArrayAdapter<Product> { 

Context context; 
ArrayList<Product> products; 
LayoutInflater vi; 
ProgressBar mSpinner; 

private ImageView imageView; 

public void setItems(ArrayList<Product> items) { 
    this.products = items; 
} 

public ProductListAdapter(Context context, ArrayList<Product> productList) { 
    super(context, 0, productList); 
    // TODO Auto-generated constructor stub 

    this.context = context; 
    this.products = productList; 

} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 

    View v = convertView; 
    final Product p = products.get(position); 

    if (p != null) { 

     if (v == null) { 

      vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.sample_singlerow, null); 
     } 

     imageView = (ImageView) v.findViewById(R.id.product_image); 
     TextView title = (TextView) v.findViewById(R.id.product_title); 
     TextView summary = (TextView) v.findViewById(R.id.product_summary); 
     TextView price = (TextView) v.findViewById(R.id.product_price); 
     TextView type = (TextView) v.findViewById(R.id.product_type); 
     ImageView pImage = (ImageView) v.findViewById(R.id.persons); 

     if (imageView != null) { 
      if (p.getImage() == null) { 
       if (p.getImageURL() != null) { 

        new AsyncImageLoader(imageView, p.getImageURL()); 

       } 
      } 
     } 

     if (title != null) { 
      Log.i("Title: ", p.getName()); 
      title.setText(p.getName()); 
     } 

     if (summary != null) { 

      Log.i("Summary: ", p.getDescription()); 
      summary.setText(p.getDescription().substring(0, 110) + "..."); 
     } 

     if (price != null) { 
      Log.i("Price: ", p.getPrice()); 
      price.setText(p.getPrice()); 
     } 

     if (type != null) { 
      Log.i("Type: ", p.getType()); 
      type.setText(p.getType() + " Person"); 
     } 

     if (pImage != null) { 

      try { 

       if (p.getType().equals("1")) { 

        pImage.setImageResource(R.drawable.one_person); 

       } else if (p.getType().equals("2")) { 

        pImage.setImageResource(R.drawable.two_person); 

       } 

      } catch (NotFoundException e) { 
       // TODO Auto-generated catch block 
       pImage.setImageDrawable(null); 
       e.printStackTrace(); 
      } 
     } 

    } 

    return v; 
} 

編輯:

公共類AsyncImageLoader { 私人最終的WeakReference imageViewReference;

public AsyncImageLoader(ImageView imageView,String imageUrl) { 
    imageViewReference = new WeakReference<ImageView>(imageView); 
    String[] url={imageUrl}; 
    new BitmapDownloaderTask().execute(url); 
} 
// static int counter = 0; 
// int imageNum = 0; 

/** 
* This Interface in used by {@link AsyncImageLoader} to return a response 
* by after loading image 
*/ 

public interface ImageCallback { 
    public Drawable temp = null; 

    /** 
    * Load the Image in imageDrable, Image is loaded form imageUrl 
    * 
    * @param imageDrawable 
    *   Image in drawable format 
    * @param imageUrl 
    *   URL of image to be load 
    */ 
    public void imageLoaded(Drawable imageDrawable, String imageUrl); 
} 

private String LOG_TAG; 


class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> { 
    private String url; 


    @Override 
    // Actual download method, run in the task thread 
    protected Bitmap doInBackground(String... params) { 
     // params comes from the execute() call: params[0] is the url. 
     return downloadBitmap(params[0]); 
    } 

    @Override 
    // Once the image is downloaded, associates it to the imageView 
    protected void onPostExecute(Bitmap bitmap) { 
     if (isCancelled()) { 
      bitmap = null; 
     } 

     if (imageViewReference != null) { 
      ImageView imageView = imageViewReference.get(); 
      if (imageView != null && !(bitmap==null)) { 
       imageView.setImageBitmap(bitmap); 
      } 
     } 
    } 
} 

Bitmap downloadBitmap(String url) { 
    final int IO_BUFFER_SIZE = 4 * 1024; 

    // AndroidHttpClient is not allowed to be used from the main thread 
    final HttpClient client = AndroidHttpClient.newInstance("Android"); 
    final HttpGet getRequest = new HttpGet(url); 

    try { 
     HttpResponse response = client.execute(getRequest); 
     final int statusCode = response.getStatusLine().getStatusCode(); 
     if (statusCode != HttpStatus.SC_OK) { 
      Log.w("ImageDownloader", "Error " + statusCode + 
        " while retrieving bitmap from " + url); 
      return null; 
     } 

     final HttpEntity entity = response.getEntity(); 
     if (entity != null) { 
      InputStream inputStream = null; 
      try { 
       inputStream = entity.getContent(); 
       // return BitmapFactory.decodeStream(inputStream); 
       // Bug on slow connections, fixed in future release. 
       return BitmapFactory.decodeStream(new FlushedInputStream(inputStream)); 
      } finally { 
       if (inputStream != null) { 
        inputStream.close(); 
       } 
       entity.consumeContent(); 
      } 
     } 
    } catch (IOException e) { 
     getRequest.abort(); 
     Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e); 
    } catch (IllegalStateException e) { 
     getRequest.abort(); 
     Log.w(LOG_TAG, "Incorrect URL: " + url); 
    } catch (Exception e) { 
     getRequest.abort(); 
     Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e); 
    } finally { 
     if ((client instanceof AndroidHttpClient)) { 
      ((AndroidHttpClient) client).close(); 
     } 
    } 
    return null; 
} 
/* 
* An InputStream that skips the exact number of bytes provided, unless it reaches EOF. 
*/ 
static class FlushedInputStream extends FilterInputStream { 
    public FlushedInputStream(InputStream inputStream) { 
     super(inputStream); 
    } 

    @Override 
    public long skip(long n) throws IOException { 
     long totalBytesSkipped = 0L; 
     while (totalBytesSkipped < n) { 
      long bytesSkipped = in.skip(n - totalBytesSkipped); 
      if (bytesSkipped == 0L) { 
       int b = read(); 
       if (b < 0) { 
        break; // we reached EOF 
       } else { 
        bytesSkipped = 1; // we read one byte 
       } 
      } 
      totalBytesSkipped += bytesSkipped; 
     } 
     return totalBytesSkipped; 
    } 
} 

}

請讓我知道什麼是問題。焦急地等待你的迴應。

+0

我猜有些事情錯在你的'AsyncImageLoader() '。你在使用什麼,你的異步任務中的任何隊列? –

+0

是的,你能否給我們提供一個AsyncImageLoader的代碼?我認爲問題出在那裏 – AlexN

+0

請參閱編輯部分..我提供了asyncImageloader的代碼 –

回答

0

正如我所看到的,你有一些麻煩與視圖中的適配器和異步加載回用。 爲了優化性能和內存,而不是反覆膨脹視圖,Android會嘗試在ListView的回收站中「緩存」列表項 - 這意味着相同的視圖(列表項)將被多次使用,每次使用不同的數據項。

如果是這樣 - 讓我們檢查會發生什麼,如果你滾動現有的列表:一些人認爲將infated,充滿了數據,並開始下載圖像ImageView的。在單獨的線程中。

現在,如果這個視圖將另一個數據項目被重用什麼,以前的圖像之前已成功加載?目前,此圖片將啓動一個新的AsyncTask。而這裏出現了一個賽車狀況,沒有人知道從哪個訂單中返回結果將從AsyncTask中返回。

因此,我建議你要麼的AsyncTask存儲與視圖(標籤,例如),或做出一些HashMap中。 主要目的 - 確定何時位圖加載完成 - 是否將此圖像用於其他位圖請求,如果它是 - 跳過圖像設置,因爲它已過時。

這種做法將阻止imageViews從另一項目顯示錯誤的圖像。

希望它能幫助,祝你好運

0

你需要添加bydefault圖像如果圖像的URL爲空,只需添加其他檢查和添加任何佔位

相關問題