Các phương thức getViewTypeCount và getItemViewType của ArrayAd CHƯƠNG


159

Ai đó bằng những từ đơn giản có thể giải thích cho tôi cách sử dụng getViewTypeCount()getItemViewType()phương pháp của ArrayAdapter?

Câu trả lời:


308

Chúng xử lý trường hợp bạn muốn các kiểu xem khác nhau cho các hàng khác nhau. Chẳng hạn, trong một ứng dụng danh bạ, bạn có thể muốn các hàng chẵn có hình ảnh ở bên trái và các hàng lẻ có hình ảnh bên phải. Trong trường hợp đó, bạn sẽ sử dụng:

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return position % 2;
}

Khung này sử dụng loại chế độ xem của bạn để quyết định chế độ xem nào sẽ trao cho bạn convertViewtrong getViewphương thức của bạn . Nói cách khác, trong ví dụ trên, các hàng chẵn của bạn sẽ chỉ nhận được các chế độ xem được tái chế với các hình ảnh ở bên trái để sử dụng lại và các hàng lẻ sẽ chỉ nhận được các hàng có hình ảnh bên phải.

Nếu mỗi hàng trong danh sách của bạn có cùng bố cục, bạn không cần phải lo lắng về các kiểu xem. Trong thực tế, BaseAd Module.java cung cấp một hành vi mặc định cho tất cả các bộ điều hợp:

public int getItemViewType(int position) {
    return 0;
}

public int getViewTypeCount() {
    return 1;
}

Điều này thực sự cung cấp cho bạn cùng một kiểu xem cho mỗi hàng.

Chỉnh sửa - để phác thảo luồng chung:

  1. Bạn liên kết dữ liệu với AdapterViewbộ chuyển đổi của bạn .
  2. Các AdapterViewcố gắng để hiển thị các mục hiển thị cho người dùng.
  3. Khung gọi getItemViewTypecho hàng n, hàng nó sắp hiển thị.
  4. Khung kiểm tra nhóm lượt xem được tái chế của nó để xem các kiểu của hàng n. Nó không tìm thấy bất kỳ vì chưa có lượt xem nào được tái chế.
  5. getViewđược gọi cho hàng n.
  6. Bạn gọi getItemViewTypecho hàng nđể xác định loại chế độ xem bạn nên sử dụng.
  7. Bạn sử dụng câu lệnh if / switch để làm tăng tệp xml khác nhau tùy thuộc vào loại chế độ xem được yêu cầu.
  8. Bạn điền vào xem với thông tin.
  9. Bạn trả lại chế độ xem, thoát getViewvà chế độ xem hàng của bạn được hiển thị cho người dùng.

Bây giờ, khi chế độ xem được tái chế bằng cách cuộn màn hình, nó sẽ đi vào nhóm chế độ xem được tái chế được quản lý bởi khung. Chúng chủ yếu được sắp xếp theo kiểu xem để chế độ xem đúng loại được cung cấp cho bạn theo convertViewtham số trong getViewphương thức của bạn :

  1. Khung một lần nữa gọi getItemViewTypecho hàng nó muốn hiển thị.
  2. Lần này, có một cái nhìn trong hồ bơi tái chế của loại thích hợp.
  3. Chế độ xem tái chế được chuyển cho bạn làm convertViewtham số cho getViewphương thức của bạn .
  4. Bạn điền vào chế độ xem tái chế với thông tin mới và trả lại.

1
@Matthew, cảm ơn câu trả lời của bạn. Bạn có thể mô tả dòng chảy như thế nào các phương thức này được gọi. Ngoài ra, tôi không hiểu làm thế nào điều này thực sự được liên kết với dữ liệu của tôi trong res / layout.
Eugene

Không có hợp đồng rõ ràng khi các phương thức này được gọi. res / layout là nơi để xem các đối tượng. Đây là một bộ chuyển đổi . Bạn nên kiểm tra loại mục trong phương thức getView của bạn và tăng chế độ xem phù hợp từ độ phân giải / bố cục tương ứng.
Matthew Willis

1
Bạn đang trả lại nó trong getItemViewType.
Matthew Willis

Bạn thực hiện liên kết theo cách thủ công trong getView: if (type == 0) {/ * Inflate R.layout.row_icon_on_left /} other {/ Inflate R.layout.row_icon_on_right * /}
Matthew Willis

75
Coi chừng! getItemViewType () phải trả về một giá trị int từ 0 đến getViewTypeCount () - 1.
PacificSky

12

Nếu chúng ta cần hiển thị loại chế độ xem khác nhau trong chế độ xem danh sách thì nên sử dụng getViewTypeCount()getItemViewType()trong bộ điều hợp thay vì bật chế độ xem View.GONEView.VISIBLEcó thể rất tốn kém trong getView()đó sẽ ảnh hưởng đến cuộn danh sách.

Vui lòng kiểm tra cái này để sử dụng getViewTypeCount()getItemViewType()trong Adaptor.

Liên kết: việc sử dụng của getviewtypecount


Trả lại IGNORE_ITEM_VIEW_TYPE trong getItemViewType () sẽ luôn chuyển 'view' thành null trong getView (vị trí int, View view, Viewgroup viewgroup) buộc phải khởi tạo tất cả các thành phần UI. Không phải đó là một chỉ báo hiệu suất kém trong trường hợp mẫu giữ, chúng ta có thể sử dụng lại các chế độ xem UI hiện có và chúng ta chỉ cần chuyển chế độ xem sang View.GONE hoặc View.VISIBLE dựa trên vị trí.
Namrata Bagerwal

11

Xem Outttt !!!!
Tôi đã phải đối mặt với một vấn đề khi thực hiện ListViewngày hôm qua và đó là hai loại chế độ xem cho các hàng bị xáo trộn ngay sau khi tôi cuộn nó. Mặc dù câu trả lời được bình chọn hàng đầu trong chủ đề này đưa ra một lời giải thích chung chung, nó vẫn không nêu bật phần thông tin quan trọng nhất để ngăn chặn lỗi UI ở trên mà tôi đã đề cập.

Dưới đây là giải thích của tôi:
Cả hai getViewTypeCount()getItemViewType()đang được sử dụng bởi BaseAdapter's getViewphương pháp để tìm ra loại một cái nhìn nó nên được lấy, tái chế và trả lại. (như được giải thích trong câu trả lời hàng đầu trong chuỗi). Nhưng nếu bạn không triển khai hai phương pháp này theo trực giác theo API API của Android, thì bạn có thể gặp phải vấn đề tôi đã đề cập.

Tóm tắt Hướng dẫn cho việc thực hiện:
Thực hiện nhiều loại Viewscho ListViewhàng của chúng ta phải thực hiện về cơ bản, getItemViewType()getViewTypeCount()phương pháp. Và getItemViewType()tài liệu cung cấp cho chúng tôi một Lưu ý như sau:

Lưu ý: Số nguyên phải nằm trong phạm vi 0đến getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPEcũng có thể được trả lại.

Vì vậy, trong bạn, getItemViewType()bạn nên trả về các giá trị cho Kiểu xem, bắt đầu từ 0, đến loại cuối cùng là (số loại - 1). Ví dụ: giả sử bạn chỉ có ba loại chế độ xem? Vì vậy, tùy thuộc vào đối tượng dữ liệu cho chế độ xem, bạn chỉ có thể trả về 0 hoặc 1 hoặc 2 từ getItemViewType()phương thức, giống như chỉ mục mảng dựa trên zero. Và khi bạn có ba loại khung nhìn được sử dụng, getViewTypeCount()phương thức của bạn phải trả về 3.

Trong mọi trường hợp nếu bạn trả về bất kỳ giá trị số nguyên nào khác như 1, 2, 3 hoặc 111, 222, 333 cho phương pháp này, bạn chắc chắn có thể gặp phải lỗi UI ở trên mà bạn vừa đặt bằng cách không tuân theo API API của Android.

Nếu bạn không nhận được manh mối hoặc vẫn không thể giải quyết và cần thêm thông tin, vui lòng đọc câu trả lời chi tiết của tôi trong chuỗi Hỏi & Đáp về StackOverflow này .

Đọc Tài liệu dành cho nhà phát triển Android để biết thêm thông tin bạn có thể tìm thấy đầu mối trực tiếp.

Hy vọng câu trả lời này có thể hữu ích cho ai đó ngoài kia để tiết kiệm nhiều giờ !!!

Chúc mừng !!!


1
Cảm ơn vì đã đề cập đến IGNORE_ITEM_VIEW_TYPEtôi đã có một lỗi trên một trong ListView của tôi. Tôi đã sử dụng một ArrayAd CHƯƠNG để chèn một khung nhìn bao gồm 1 hình ảnh và 2 chế độ xem văn bản. Tôi chỉ có một kiểu xem. Tôi đã cố gắng không ghi đè phương thức getItemViewType hoặc ghi đè lên nó bằng cách trả về vị trí hoặc số nguyên được mã hóa cứng. Trong mọi trường hợp, tôi đã gặp phải sự trùng lặp trong danh sách của mình, với hành vi kỳ quặc khi cuộn (trùng lặp thay đổi). Trở lại IGNORE_ITEM_VIEW_TYPEtrong phương pháp đã khắc phục vấn đề. Cảm ơn.
Alex

@Alex rất vui vì nó hữu ích cho bạn! :-)
Randika Vishman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.