2012-11-08 18 views
38

Tôi đã học được rằng để tối đa hóa hiệu quả với các bản xem danh sách Android, bạn chỉ nên có nhiều lượt xem 'tăng' khi cần để vừa với màn hình. Khi chế độ xem đã di chuyển khỏi màn hình, bạn nên sử dụng lại chế độ đó theo phương pháp getView của mình, kiểm tra xem convertView có bị vô hiệu hay không.Sử dụng lại các chế độ xem trong Chế độ xem danh sách Android với 2 bố cục khác nhau

Tuy nhiên, làm cách nào bạn có thể triển khai ý tưởng này khi bạn cần 2 bố cục khác nhau cho danh sách? Cho phép nói rằng một danh sách các đơn đặt hàng và 1 bố cục là cho các đơn đặt hàng đã hoàn thành và bố cục khác dành cho các đơn đặt hàng quá trình.

Đây là hướng dẫn ví dụ về ý tưởng mà mã của tôi đang sử dụng. Trong trường hợp của tôi, tôi sẽ phải bố trí 2 hàng: R.layout.listview_item_product_completeR.layout.listview_item_product_inprocess

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

ViewHolder holder = null; 

if (convertView == null) { 
    holder = new ViewHolder(); 
    if(getItemViewType(position) == COMPLETE_TYPE_INDEX) { 
     convertView = mInflator.inflate(R.layout.listview_item_product_complete, null); 
     holder.mNameTextView = (TextView) convertView.findViewById(R.list.text_complete); 
     holder.mImgImageView = (ImageView) convertView.findViewById(R.list.img_complete); 
    } 
    else { // must be INPROCESS_TYPE_INDEX 
     convertView = mInflator.inflate(R.layout.listview_item_product_inprocess, null); 
     holder.mNameTextView = (TextView) convertView.findViewById(R.list.text_inprocess); 
     holder.mImgImageView = (ImageView) convertView.findViewById(R.list.img_inprocess); 
    } 
    convertView.setTag(holder); 
} else { 
    holder = (ViewHolder) convertView.getTag(); 
} 
    thisOrder = (Order) myOrders.getOrderList().get(position); 
    // If using different views for each type, use an if statement to test for type, like above 
    holder.mNameTextView.setText(thisOrder.getNameValue()); 
    holder.mImgImageView.setImageResource(thisOrder.getIconValue()); 
    return convertView; 
} 

public static class ViewHolder { 
    public TextView mNameTextView; 
    public ImageView mImgImageView; 
} 
+0

Gần đây tôi đã gặp sự cố này. Tôi đã sử dụng 2 bố trí khác nhau để điền vào một listview và nó dẫn đến tình trạng hỗn loạn hoàn toàn. Tôi đã đi qua mã của tôi một lần nữa và một lần nữa nhưng không thể làm việc ra lý do tại sao bố trí sai đã được tái sử dụng. Cuối cùng, tôi quyết định chỉ gắn bó với * một * bố trí cho mỗi danh sách, nhưng rất nhiều sửa đổi chế độ xem đó dựa trên loại mục. Có rất nhiều bạn có thể làm để chỉnh sửa các mục trong mã. –

Trả lời

83

Bạn cần phải cho xem tái chế của bộ chuyển đổi biết rằng có nhiều hơn một cách bố trí và làm thế nào để phân biệt giữa hai cho mỗi hàng. Đơn giản chỉ cần ghi đè lên các phương pháp:

@Override 
public int getItemViewType(int position) { 
    // Define a way to determine which layout to use, here it's just evens and odds. 
    return position % 2; 
} 

@Override 
public int getViewTypeCount() { 
    return 2; // Count of different layouts 
} 

Kết hợp getItemViewType() bên getView(), như thế này:

if (convertView == null) { 
    // You can move this line into your constructor, the inflater service won't change. 
    mInflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE); 
    if(getItemViewType(position) == 0) 
     convertView = mInflater.inflate(R.layout.listview_item_product_complete, parent, false); 
    else 
     convertView = mInflater.inflate(R.layout.listview_item_product_inprocess, parent, false); 
    // etc, etc... 

Xem Android của Romain Guy discuss the view recycler tại Google Talks.

+0

OK, vì vậy chủ sở hữu đóng vai trò như một bản sao của các con trỏ đến các Chế độ xem khác nhau có trong bố cục của hàng. Trong trường hợp của tôi, cả hai bố cục sẽ có cùng loại trường (chỉ được định dạng khác nhau). Vì vậy, tôi sẽ chỉ cần một người giữ, đúng không? Và nếu một bố cục có một TextView và ImageView trong khi một bố cục khác có 2 TextView thì tôi sẽ cần 2 người khác nhau, phải không? – jamis0n

+2

"Trong trường hợp của tôi, cả hai bố cục sẽ có cùng các loại trường (chỉ được định dạng khác nhau). Vì vậy, tôi chỉ cần một chủ sở hữu." Yup, điều này là chính xác. "Và nếu một bố cục có một TextView và ImageView trong khi một bố cục khác có 2 TextView thì tôi sẽ cần 2 người khác nhau, phải không?" Bạn có thể có hai ViewHolders khác nhau hoặc bạn có thể kết hợp ViewHolders nhưng chỉ truy cập các thành viên thích hợp cho mỗi bố cục. Điều đó có ý nghĩa? – Sam

+0

Bạn là người đàn ông! Nó không bao giờ hoạt động lần đầu tiên! Ngoại trừ với hướng dẫn của bạn Haha ... Vì vậy, đối với sự hiểu biết của tôi, người giữ chỉ là giữ một con trỏ đến mỗi lần xem trong bố trí hàng. Nó hoặc là nhận được những từ bố trí vừa được thổi phồng khi ConvertView là null HOẶC nó kỳ diệu chọn lên các con trỏ từ cuộc gọi đến 'holder = (ViewHolder) convertView.getTag();'. Tôi có hiểu điều này không? Tôi cũng đã cập nhật mã cuối cùng của mình ở trên ... Cảm ơn một lần nữa! – jamis0n

9

Không cần phải tự mình tạo ra giải pháp chỉ cần ghi đè getItemViewType() và getViewTypeCount().

Xem các bài viết trên blog sau đây cho một ví dụ http://sparetimedev.blogspot.co.uk/2012/10/recycling-of-views-with-heterogeneous.html

Như blog giải thích, Android không thực sự đảm bảo rằng getView sẽ nhận được đúng loại xem.

+1

Tôi chưa gặp sự cố này ...Đây có phải là blog của bạn (tôi nhận thấy rằng nó được viết bởi "Andy")? Tôi sẽ đặt cược rằng 'getDirItem()' có lỗi không phải là trình tái chế khung nhìn. – Sam

+0

Đúng, đó là blog của tôi. Tiền cược - Bao nhiêu? :) Nghiêm túc, bình luận của bạn đã làm cho tôi nghi ngờ bản thân mình, vì vậy tôi đã đi và ba kiểm tra mã của tôi + thêm một số gỡ lỗi nhiều hơn nữa. Đó chắc chắn là trường hợp mà Android đôi khi đi qua quan điểm sai. Đầu mối là tôi đang sử dụng phương thức getItemViewType() trong getView() để xác định kiểu. Vì vậy, ngay cả khi điều này là sai, trừ khi nó được trả lại kết quả ngẫu nhiên (khá chắc chắn đây không phải là trường hợp đó!), Sau đó Android là đi qua xem sai. – Andy

+0

Tôi chưa từng nghe về vấn đề này trước đây ... Bạn có bất kỳ nguồn độc lập nào để xác nhận điều này không? Tôi không thấy nó và không thể tìm thấy. Nếu không nhìn thấy tất cả mã, bạn không thể thấy điều gì thực sự xảy ra trong mã của mình. Nhưng đối với người mới bắt đầu các giá trị cho 'TYPE_DIR' và' TYPE_PIC' là gì? – Sam

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