2011-09-26 30 views
12

Tôi có một ListView và một BaseAdapter.I đang tải xuống Sản phẩm từ webservice và hiển thị trên listview.It hiển thị đúng trên listview.Thứ tự các hàng trong Listview thay đổi ngẫu nhiên khi cuộn danh sách trong android

Nhưng khi tôi cuộn ListView hiển thị các hàng ở vị trí ngẫu nhiên có nghĩa là đôi khi hiển thị hàng thứ ba ở vị trí đầu tiên, hiển thị hàng vị trí giữa ở vị trí cuối cùng v.v.

Đây là lớp adapter của tôi

public class ProductListAdapter extends BaseAdapter implements OnClickListener{ 

    LayoutInflater inflater; 
    ArrayList<Product> arrProducts; 
    Context c; 

    public ProductListAdapter(Context c, ArrayList<Product> arrProducts) { 
     super(); 
     inflater = LayoutInflater.from(c); 
     this.arrProducts = arrProducts; 
     this.c = c; 
    } 

    @Override 
    public int getCount() { 
     return arrProducts.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return arrProducts.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View v, ViewGroup parent) { 
     Product product = null; 
     if(v == null) { 
      v = inflater.inflate(R.layout.product_listview_row, null); 
      product = (Product) getItem(position); 
      v.setTag(product); 
     }else { 
      product = (Product)v.getTag(); 
     } 

     v.setOnClickListener(this); 

     TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname); 
     tvProductname.setText(product.getTitle()); 

     String strReviewCount = product.getReviews(); 
     TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews); 
     if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews"); 

     Button btnPrice = (Button)v.findViewById(R.id.btnPrice); 
     btnPrice.setText(product.getSellingPrice()); 

     return v; 
    } 

    @Override 
    public void onClick(View v) { 
     Product product = (Product) v.getTag(); 
     Intent i = new Intent(c, ProductDetails.class); 
     i.putExtra(Product.PROD_ID, product.getId()); 
     startActivity(i); 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return super.getItemViewType(position); 
    } 

    @Override 
    public int getViewTypeCount() { 
     return super.getViewTypeCount(); 
    } 
} 

Đây là ListView trên layout XML

<ListView android:id="@+id/lstProducts" style="@style/fill_parent" 
     android:dividerHeight="1dp" android:divider="#dbd3c5" 
     android:scrollbars="vertical" android:layout_below="@id/layLine"></ListView> 

Ngoài ra khi tôi thay đổi getView() phương pháp BaseAdapter như thế này nó đang làm việc tốt

@Override 
    public View getView(int position, View v, ViewGroup parent) { 
     Product product = null; 
     v = inflater.inflate(R.layout.product_listview_row, null); 
     product = (Product) getItem(position); 
     v.setTag(product); 
     v.setOnClickListener(this); 

     TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname); 
     tvProductname.setText(product.getTitle()); 

     String strReviewCount = product.getReviews(); 
     TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews); 
     if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews"); 

     Button btnPrice = (Button)v.findViewById(R.id.btnPrice); 
     btnPrice.setText(product.getSellingPrice()); 

     return v; 
    } 

Nhưng vấn đề trong loại này là tôi đang hiển thị hình ảnh của sản phẩm trên hàng listview mà tôi đã không xem xét ở đây.Bằng cách sử dụng kiểu mã này getView() phương pháp luôn tạo Chế độ xem mới khi cuộn của listView để tôi phải Tôi đã sử dụng ImageLoader lớp đang sử dụng cash memory để tải xuống hình ảnh nhưng vấn đề là khi tôi đặt hình ảnh thành ImageView nhiều lần nó cho tôi out of memory error.

Hãy giúp tôi giải quyết vấn đề này.

Cảm ơn

Trả lời

10

tôi hạ cánh ở đây vì một liên kết đến các giải pháp đúng.

Vấn đề ở đây là bạn liên kết sản phẩm của mình một lần với chế độ xem khi bạn tạo chế độ xem mới. Bạn nên gọi đây trên tất cả các cuộc gọi của getView:

product = (Product) getItem(position); 
v.setTag(product); 

Nhưng bạn có thể gọi v.setOnClickListener(this) khi bạn tạo các view (nó sẽ không thay đổi anyway).

Điều này sẽ thực hiện thủ thuật. Việc triển khai loại chế độ xem chỉ bị lạm dụng ở đây. Tôi khuyên bạn nên đọc my answer here ...

+0

Tôi biết câu trả lời của tôi là không phải là cách chính xác để được sử dụng nhưng đối với tạm thời tôi đã quản lý nó bằng cách sử dụng kiểu xem. Hy vọng giải pháp của bạn hoạt động và được kiểm tra. –

+0

Cảm ơn bạn. Tôi hy vọng bạn không cảm thấy bị xúc phạm, đó không phải là ý định của tôi. Vấn đề ở đây là mọi người chấp nhận thủ thuật * như bình thường và làm việc và sau đó trở nên thực sự bối rối khi mọi thứ xảy ra sau đó hoặc họ muốn sử dụng triển khai kiểu xem thực ... Tôi chỉ muốn nó rõ ràng, thay vì bắt đầu tin đồn; -) – Knickedi

+0

Không không, cũng tốt cho tôi để có được giải pháp chính xác. Cá nhân tôi nghĩ rằng câu trả lời của bạn chắc chắn sẽ làm việc và tôi cũng sẽ thử nó. Và cảm thấy tồi tệ là không bao giờ là một trường hợp, tôi cũng ở đây để tìm hiểu. Điều này là có một cái gì đó mới từ bạn. Cảm ơn. –

5

Do đó, theo các recommendations do Knickedi, phương pháp getView() nên hình như:

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

    TextView tvProductname; 
    TextView tvReviewsCounts; 
    Button btnPrice; 

    // Phase 1... 
    if (v == null) { 
     v = inflater.inflate(R.layout.product_listview_row, null); 
     v.setOnClickListener(this); 

     tvProductname = (TextView)v.findViewById(R.id.tvProductname); 
     tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews); 
     btnPrice = (Button)v.findViewById(R.id.btnPrice); 

     v.setTag(R.id.tvProductname, tvProductname); 
     v.setTag(R.id.tvReviews, tvReviewsCounts); 
     v.setTag(R.id.btnPrice, btnPrice); 
    } 
    else { 
     tvProductname = (TextView) v.getTag(R.id.tvProductname); 
     tvReviewsCounts = (TextView) v.getTag(R.id.tvReviews); 
     btnPrice = (Button) v.getTag(R.id.btnPrice); 
    } 

    // Phase 2... 
    Product product = (Product) getItem(position); 

    tvProductname.setText(product.getTitle()); 
    btnPrice.setText(product.getSellingPrice()); 

    String strReviewCount = product.getReviews(); 
    if(strReviewCount != null) 
     tvReviewsCounts.setText(strReviewCount +" Reviews"); 

    return v; 
} 
+0

Hãy cẩn thận 'public void setTag (int key, Object tag)' đã được thêm vào trong API Level 4 ... – eightyfive

Các vấn đề liên quan