2010-07-08 21 views
8

Tôi có một ListView với một bộ điều hợp danh sách tùy chỉnh. Trong phương thức getView(), đang sử dụng mẫu 'ViewHolder' như được hiển thị trong Bản trình diễn API cho ListView14.java. Khi tôi lần đầu tiên hiển thị danh sách có vẻ như tải chính xác. Tuy nhiên, vấn đề tôi đang gặp phải là khi tôi cuộn danh sách, tôi thấy dữ liệu cho danh sách hiển thị trong hàng sai (tức là một TextView phải nằm trong hàng 10 sẽ hiển thị trong hàng 2 ví dụ). Tuy nhiên, khi tôi không sử dụng trình xem và thay vào đó gọi hàm findViewById() mỗi lần, thì chế độ xem danh sách sẽ hiển thị chính xác.android viewview viewholder. khi nào sử dụng và khi không đến

Trả lời

10

Tuy nhiên, vấn đề tôi đang chạy vào là rằng khi tôi di chuyển danh sách, tôi nhìn thấy những dữ liệu cho danh sách xuất hiện trong các hàng sai (tức là một TextView mà phải ở trong hàng 10 đang hiển thị trong hàng 2 chẳng hạn).

Rất có thể, bạn đang tái chế không đúng các hàng của mình, chẳng hạn như ViewHolders bạn đang thao tác không phải là thứ phù hợp với hàng bạn đang quay trở lại.

Here is a free excerpt từ một trong những cuốn sách của tôi để tìm hiểu thêm về việc tái chế hàng - có lẽ nó sẽ giúp bạn xác định nơi mọi thứ đang diễn ra sai.

+2

đó là một hướng dẫn thực sự tuyệt vời, cảm ơn bạn. – eric2323223

1

vì vậy tôi nghĩ rằng tôi đã phát hiện sự cố thực sự ở đây. khi bạn thiết lập các thông số bố trí trên bay cho mỗi hàng, bạn cần phải chắc chắn rằng bạn làm điều đó cho tất cả các điều kiện. vấn đề của tôi là nếu nó là hàng đầu tiên, tôi đặt một tham số layout (như padding hoặc margins etc), nhưng sau đó nếu nó là một hàng ở giữa, tôi đã không thiết lập rõ ràng các params nghĩ rằng nó sẽ chỉ sử dụng bởi inflater xem. Điều này giải thích tại sao nó hoạt động khi tôi tăng lượt xem mỗi lần. Đây là một trước & sau:

TRƯỚC:

if (position == 0) { 

      layoutParams.topMargin = uiHelper.getDip(15.0f); 
      layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 
        RelativeLayout.TRUE); 
      holder.actionMenu.setLayoutParams(layoutParams); 

      holder.contentLayout.setBackgroundResource(R.drawable.top_row); 

     } else if (position == posts.size() - 1) { 
      holder.contentLayout 
        .setBackgroundResource(R.drawable.bottom_row); 

      holder.contentLayout.setPadding(holder.contentLayout 
        .getPaddingLeft(), 
        holder.contentLayout.getPaddingTop(), 
        holder.contentLayout.getPaddingRight(), 
        holder.contentLayout.getPaddingBottom() + uiHelper.getDip(10.0f)); 

     } else { 
      holder.contentLayout 
        .setBackgroundResource(R.drawable.inner_row); 
     } 

SAU: `

  layoutParams.topMargin = uiHelper.getDip(10.0f); 
     holder.contentLayout.setPadding(holder.contentLayout 
       .getPaddingLeft(), 
       holder.contentLayout.getPaddingTop(), 
       holder.contentLayout.getPaddingRight(), 
       uiHelper.getDip(10.0f)); 
     if (position == 0) { 

      layoutParams.topMargin = uiHelper.getDip(15.0f); 
      layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 
        RelativeLayout.TRUE); 

      holder.contentLayout.setBackgroundResource(R.drawable.top_row); 

     } else if (position == posts.size() - 1) { 
      holder.contentLayout 
        .setBackgroundResource(R.drawable.bottom_row); 

      holder.contentLayout.setPadding(holder.contentLayout 
        .getPaddingLeft(), 
        holder.contentLayout.getPaddingTop(), 
        holder.contentLayout.getPaddingRight(), 
        uiHelper.getDip(20.0f)); 

     } else { 

      holder.contentLayout 
        .setBackgroundResource(R.drawable.inner_row); 

     } 

     holder.actionMenu.setLayoutParams(layoutParams); 
2
  • tôi phải đối mặt với cùng một vấn đề
  • Giải Quyết sử dụng dưới đây techninc
  • Lý do: Adapter không Đã tải thường xuyên.
  • trong lớp Tuỳ chỉnh Adaptor của bạn thêm ViewHolder sử dụng Access Specifiers

    private static class ViewHolder { 
    
         protected TextView itemName; 
    
        } 
    

Trong Get Xem phương pháp

@Override 

     public View getView(int position, View view, ViewGroup viewGroup) { 

      // create a ViewHolder reference 
      ViewHolder holder; 

      //check to see if the reused view is null or not, if is not null then reuse it 
      if (view == null) { 
       holder = new ViewHolder(); 

       view = mLayoutInflater.inflate(R.layout.list_item, null); 
       holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view); 

       // the setTag is used to store the data within this view 
       view.setTag(holder); 
      } else { 
       // the getTag returns the viewHolder object set as a tag to the view 
       holder = (ViewHolder)view.getTag(); 
      } 
    // now Use Holder object toget Idss 

    holder.itemName.setText(" sample text based on position "); 
    } 

Chú ý: Và Chúng ta không nên đặt bất kỳ thẻ để xem đối tượng ngoại trừ Đối tượng trình xem

+0

Cảm ơn bạn rất nhiều vì đoạn mã hữu ích này. – swiftBoy

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