2012-04-12 38 views
87

Câu hỏi của tôi là: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?

  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 viết mà tôi đã đọc kiểm tra nếu convertview là null hay không đầu tiên? Nó có nghĩa là gì khi nó là null và nó có nghĩa là gì khi nó không phải là?
  3. Thông số gốc mà phương thức này chấp nhận là gì?

Trả lời

103

1: LayoutInflater lấy bố cục tệp XML của bạn và tạo các đối tượng Chế độ xem 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 điều này là null nó có nghĩa là không có chế độ xem tái chế và chúng ta phải tạo một cái mới, nếu không chúng ta nên sử dụng nó để tránh tạo một cái mới.

3: parent được cung cấp để bạn có thể tăng lượt xem của bạn vào đó cho các thông số bố cục phù hợp.

Tất cả này lại với nhau có thể được sử dụng để tạo hiệu quả quan điểm cho rằng sẽ xuất hiện trong danh sách của bạn (hoặc xem khác mà phải mất một bộ chuyển đổi):

public View getView (int position, 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; 
} 

Thông báo việc sử dụng các LayoutInflater, mà parent thể được sử dụng làm đối số cho nó và cách sử dụng lại convertView.

+4

Convertview == null là hữu ích khi tất cả itens của bạn theo cùng một bố trí. Ví dụ: khi bạn cần kiểm tra radio hoặc nút được chọn và thay đổi bố cục dựa trên từng mục, bạn cần phải phát lại hoặc hiển thị chế độ xem được lưu vào bộ nhớ cache. – sagits

+0

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

+0

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

9

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

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

  1. Nó thổi phồng bố trí (các file xml trên res của bạn/layout/thư mục) vào java Objects như LinearLayout và quan điểm khác.

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

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

4
  1. Layout inflator thổi phồng/thêm XML bên ngoài để 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ó xem tăng cao, chúng tôi không muốn làm điều đó một lần nữa kể từ khi lạm phát là một quá trình tốn kém .. đó là lý do tại sao chúng tôi kiểm tra nếu nó null và sau đó thổi phồng nó.

  3. Quan điểm cha mẹ là di động duy nhất của Danh sách của bạn ..

+3

Chế độ xem cha mẹ được giải thích không chính xác ở đây. Nó sẽ là ListView không ListItem –

2

LayoutInflater được sử dụng để tạo ra quan điểm năng động của XML cho ListView mục hoặc trong onCreateView của đoạn.

ConvertView về 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ó ListView có thể cuộn. Khi cuộn xuống hoặc xuống, convertView sẽ cung cấp chế độ xem được cuộn. Reusage này tiết kiệm bộ nhớ.

Tham số cha của phương thức getView() cho biết tham chiếu đến bố cục gốc có listView. Giả sử bạn muốn để có được Id của bất kỳ mục trong XML 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 View hoặc ViewGroup cho mỗi hàng của Listview hoặc Spinner. Bạn có thể xác định điều này View hoặc ViewGroup trong một tệp Layout XML trong thư mục res/layout và có thể cung cấp tham chiếu đến đối tượng lớp Adapter.

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

LayoutInflater class có phương thức inflate() whic tạo View Object từ bố cục tài nguyên XML.

61

getView() phương pháp trong Adapter là để tạo ra cái nhìn 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 thường một LinearLayout, FrameLayout, hoặc RelativeLayout)

  2. convertView là để tái chế. Giả sử bạn có một listview mà chỉ có thể hiển thị 10 mục tại một thời điểm, và hiện tại nó là hiển thị mục 1 -> mục 10. Khi bạn cuộn xuống một mục, mục 1 sẽ không còn 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 mục 1 (không cần thiết nữa). Vì vậy, thay vì tạo đối tượng Xem mới cho mục 11 (là tốn kém), tại sao không sử dụng lại convertView? => chúng tôi chỉ cần kiểm tra convertView là không hoặc không, nếu null tạo chế độ xem mới, hãy sử dụng lại convertView.

  3. parentView là chế độ xem có chế độ xem của mục mà getView() tạo ra. Thông thường nó là ListView hoặc Gallery ...

Note: bạn không gọi phương pháp này trực tiếp, chỉ cần thực hiện nó để nói với cái nhìn mẹ làm thế nào để tạo ra quan điểm của item.

+2

Giải thích TUYỆT VỜI cho parentView, không thể tìm thấy giải thích tốt hơn so với giải thích này, +1 –

+0

Giải thích tuyệt vời! – gabi

+0

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

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 yếu tố giao diện người dùng của bạn chỉ là 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ì các inflater là cho. Các inflater, sử dụng các thẻ và các thông số tương ứng của họ để tạo ra các đối tượng thực tế và thiết lập tất cả các tham số. Sau này, bạn có thể lấy một tham chiếu đến phần tử UI bằng cách sử dụng findViewById().

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

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

Bạn cũng phải bắt gặp khái niệm về 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 tăng. Bằng cách này, chúng ta có thể tránh gọi rất nhiều findByViewId() và tiết kiệm rất nhiều thời gian. ViewHolder này được tạo ra trong điều kiện (convertView == null) và được lưu trữ trong convertView sử dụng setTag(). Trong vòng lặp khác, chúng ta lấy lại nó bằng cách sử dụng getView() và tái sử dụng nó.

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

Cha mẹ là một Nhóm xem 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.

Hy vọng điều này sẽ giúp ích:

0

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

/** 
* 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); 
Các vấn đề liên quan