Phương thức getView () hoạt động như thế nào khi tạo bộ điều hợp tùy chỉnh của riêng bạn?


101

Câu hỏi của tôi là:

  1. Chức năng chính xác của LayoutInflater là gì?
  2. Tại sao tất cả các bài báo mà tôi đã đọc đều kiểm tra xem convertview có phải là null hay không trước tiên? Nó có nghĩa là gì khi nó là null và nó có nghĩa là gì khi nó không?
  3. Tham số cha mà phương thức này chấp nhận là gì?

Câu trả lời:


115

1: The LayoutInflaterlấy các tệp XML bố cục của bạn và tạo các đối tượng View khác nhau từ nội dung của nó.

2: Bộ điều hợp được xây dựng để sử dụng lại Chế độ xem, khi Chế độ xem được cuộn để không còn hiển thị nữa, nó có thể được sử dụng cho một trong các Chế độ xem mới xuất hiện. Chế độ xem được sử dụng lại này là convertView. Nếu giá trị này không có nghĩa là không có Chế độ xem tái chế và chúng ta phải tạo một Chế độ xem mới, nếu không chúng ta nên sử dụng nó để tránh tạo một Chế độ xem mới.

3: Cái parentđược cung cấp để bạn có thể thổi phồng chế độ xem của mình vào đó để có các thông số bố cục phù hợp.

Tất cả những thứ này cùng nhau có thể được sử dụng để tạo hiệu quả chế độ xem sẽ xuất hiện trong danh sách của bạn (hoặc chế độ xem khác có bộ điều hợp):

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

Lưu ý việc sử dụng LayoutInflater, parentcó thể được dùng làm đối số cho nó và cách convertViewsử dụng lại.


5
Convertview == null hữu ích khi tất cả các vòng lặp của bạn tuân theo cùng một bố cục. Ví dụ, khi bạn cần kiểm tra một radio hoặc nút đã chọn và thay đổi bố cục dựa trên từng mục, bạn cần phải điều chỉnh lại hoặc nó nhận được chế độ xem được lưu trong bộ nhớ cache.
sagits

Không cần quá lạm phát. Chỉ cần bạn viết switch hoặc if-else bậc thang trong getview và tăng các lượt xem tùy theo trường hợp của bạn, ghi đè public int getItemViewType (int position) và public int getViewTypeCount (). @sagits
Prashanth Debbadwar

Nếu các câu lệnh thường hoạt động, nhưng khi sử dụng các nút radio, chỉnh sửa văn bản và loại nội dung này, tôi đã gặp sự cố khi sử dụng các chế độ xem được lưu trong bộ nhớ cache, có một số câu hỏi liên quan đến nội dung này khi tràn ngăn xếp.
sagits

71

getView()phương pháp trong Adapter là để xem tạo mục của một ListView, Gallery...

  1. LayoutInflaterđược sử dụng để có được Xem đối tượng mà bạn định nghĩa trong một xml bố trí (đối tượng gốc, thường là một LinearLayout, FrameLayouthay RelativeLayout)

  2. convertViewlà để tái chế. Giả sử bạn có chế độ xem danh sách chỉ có thể hiển thị 10 mục cùng một lúc và hiện tại nó đang hiển thị mục 1 -> mục 10. Khi bạn cuộn xuống một mục, mục 1 sẽ nằm ngoài màn hình và mục 11 sẽ được hiển thị . Để tạo Chế độ xem cho mục 11, phương thức getView () sẽ được gọi, và convertViewđây là chế độ xem của mục 1 (không còn cần thiết nữa). Vì vậy, thay vì tạo một đối tượng View mới cho mục 11 (tốn kém), tại sao không sử dụng lại convertView? => chúng ta chỉ kiểm tra convertViewlà null hay không, nếu null thì tạo view mới, còn lại thì sử dụng lại convertView.

  3. parentViewlà ListView hoặc Thư viện ... chứa chế độ xem của mục sẽ getView()tạo ra.

Lưu ý : bạn không gọi phương thức này trực tiếp, chỉ cần triển khai nó để cho chế độ xem gốc biết cách tạo chế độ xem của mục.


2
Lời giải thích tuyệt vời cho parentView, không thể tìm thấy lời giải thích tốt hơn thế này, 1
Ahmed Adel Ismail

Lời giải thích tuyệt vời!
gabi

lời giải thích tuyệt vời +1
tpk

8

Bạn có thể xem video này về chế độ xem danh sách. Nó có từ những năm trước Google IO và vẫn là lượt xem danh sách tốt nhất trong tâm trí tôi.

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. Nó thổi phồng các bố cục (các tệp xml trên res / layout / folder của bạn) thành các Đối tượng java như LinearLayout và các dạng xem khác.

  2. Xem video, bạn sẽ được cập nhật về việc sử dụng chế độ xem chuyển đổi là gì, về cơ bản nó là chế độ xem tái chế đang chờ bạn sử dụng lại, để tránh việc tạo đối tượng mới và làm chậm việc cuộn danh sách của bạn.

  3. Cho phép bạn tham chiếu chế độ xem danh sách từ bộ điều hợp.


5

Chức năng chính xác của LayoutInflater là gì?

Khi bạn thiết kế bằng XML, tất cả các phần tử giao diện người dùng của bạn chỉ là các thẻ và thông số. Trước khi bạn có thể sử dụng các phần tử giao diện người dùng này, (ví dụ: TextView hoặc LinearLayout), bạn cần tạo các đối tượng thực tế tương ứng với các phần tử xml này. Đó là những gì máy bơm hơi dùng cho. Bộ thổi phồng, sử dụng các thẻ này và các tham số tương ứng của chúng để tạo các đối tượng thực tế và thiết lập tất cả các tham số. Sau đó, bạn có thể nhận được tham chiếu đến phần tử giao diện người dùng bằng cách sử dụng findViewById ().

Tại sao tất cả các bài báo mà tôi đã đọc đều kiểm tra xem convertview có phải là null hay không trước tiên? Nó có nghĩa là gì khi nó là null và nó có nghĩa là gì khi nó không?

Đây là một điều thú vị. Bạn thấy đấy, getView () được gọi mỗi khi một mục trong danh sách được vẽ. Bây giờ, trước khi vật phẩm có thể được vẽ, nó phải được tạo ra. Bây giờ convertView về cơ bản là khung nhìn được sử dụng cuối cùng để vẽ một mục. Trong getView (), bạn tăng xml trước rồi sử dụng findByViewID () để lấy các phần tử giao diện người dùng khác nhau của listitem. Khi chúng tôi kiểm tra (convertView == null) những gì chúng tôi làm là kiểm tra xem nếu một chế độ xem là null (đối với mục đầu tiên) thì hãy tạo nó, nếu không, nếu nó đã tồn tại, hãy sử dụng lại nó, không cần phải thực hiện lại quá trình thổi phồng . Làm cho nó hiệu quả hơn rất nhiều.

Chắc hẳn bạn cũng đã bắt gặp khái niệm ViewHolder trong getView (). Điều này làm cho danh sách hiệu quả hơn. Những gì chúng tôi làm là tạo một trình xem và lưu trữ tham chiếu đến tất cả các phần tử giao diện người dùng mà chúng tôi nhận được sau khi thổi phồng. Bằng cách này, chúng ta có thể tránh gọi nhiều findByViewId () và tiết kiệm rất nhiều thời gian. ViewHolder này được tạo trong điều kiện (convertView == null) và được lưu trữ trong convertView bằng cách sử dụng setTag (). Trong vòng lặp khác, chúng ta chỉ lấy lại nó bằng getView () và sử dụng lại nó.

Tham số cha mà phương thức này chấp nhận là gì?

Cha mẹ là một ViewGroup mà chế độ xem của bạn được tạo bởi getView () cuối cùng được đính kèm. Bây giờ trong trường hợp của bạn, đây sẽ là ListView.

Hi vọng điêu nay co ich :)


4
  1. Bộ thổi phồng bố cục thổi phồng / thêm XML bên ngoài vào chế độ xem hiện tại của bạn.

  2. getView () được gọi nhiều lần kể cả khi được cuộn. Vì vậy, nếu nó đã có lượt xem bị thổi phồng, chúng tôi không muốn làm lại vì việc thổi phồng là một quá trình tốn kém .. đó là lý do tại sao chúng tôi kiểm tra xem nó có rỗng hay không và sau đó thổi phồng nó lên.

  3. Chế độ xem chính là một ô trong Danh sách của bạn ..


3
Chế độ xem của phụ huynh được giải thích không chính xác ở đây. Nó sẽ là ListView không phải là ListItem
Varun Jain

2

LayoutInflaterđược sử dụng để tạo các khung nhìn động của XML cho ListViewmục hoặc trong onCreateViewphân đoạn.

ConvertViewvề cơ bản được sử dụng để tái chế các chế độ xem hiện không có trong chế độ xem. Giả sử bạn có một cuộn có thể cuộn ListView. Khi cuộn xuống hoặc cuộn lên, convertViewchế độ xem đã được cuộn. Việc sử dụng lại này giúp tiết kiệm bộ nhớ.

Tham số cha của getView()phương thức cung cấp một tham chiếu đến bố cục mẹ có listView. Giả sử bạn muốn lấy Id của bất kỳ mục nào trong XML gốc mà bạn có thể sử dụng:

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }

1

getView()phương pháp tạo mới Viewhoặc ViewGroupcho mỗi hàng Listviewhoặc Spinner. Bạn có thể xác định điều này Viewhoặc ViewGrouptrong một Layout XMLtệp trong res/layoutthư mục và có thể cung cấp tham chiếu nó cho AdapterĐối tượng lớp.

nếu bạn có 4 mục trong Mảng được chuyển đến Bộ điều hợp. getView()phương thức này sẽ tạo 4 View cho 4 hàng Adaper.

Lớp LayoutInflater có một Phương thức phồng lên () để tạo Đối tượng Xem từ bố cục tài nguyên XML.


0

Bạn cũng có thể tìm thấy thông tin hữu ích về getView tại giao diện Bộ điều hợp trong tệp Adapter.java. Nó nói rằng;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
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.