2014-09-22 13 views
10

Tôi có một đoạn mã đơn giản để triển khai listview tùy chỉnh.Hoạt động của setTag và getTag trong mẫu ViewHolder là gì?

Mã của tôi là như sau:

WeatherAdapter.java:

public class WeatherAdapter extends ArrayAdapter<weather>{ 

    Context mcontext; 
    int mlayoutResourceId;  
    weather mdata[] = null; 
    View row; 

    public WeatherAdapter(Context context, int layoutResourceId, weather[] data) { 
     super(context, layoutResourceId, data); 
     mlayoutResourceId = layoutResourceId; 
     mcontext = context; 
     mdata = data; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     row = convertView; 
     WeatherHolder holder = null; 

     if(row == null) 
     { 
      LayoutInflater inflater = ((Activity) mcontext).getLayoutInflater(); 
      row = inflater.inflate(mlayoutResourceId, parent, false); 

      holder = new WeatherHolder(row); 


      row.setTag(holder); 

     } 
     else 
     { 
      holder = (WeatherHolder)row.getTag(); 
     } 

     weather w = mdata[position]; 
     holder.txtTitle.setText(w.mtitle); 
     holder.imgIcon.setImageResource(w.micon); 

     return row; 
    } 

WeatherHolder.java:

class WeatherHolder 
    { 
     ImageView imgIcon; 
     TextView txtTitle; 


    public WeatherHolder(View v){ 

      imgIcon = (ImageView)row.findViewById(R.id.imgIcon); 
      txtTitle = (TextView)row.findViewById(R.id.txtTitle); 

    } 
    } 
} 

Tôi đã thấy câu trả lời rất nhiều trên SO và khác các trang web và tôi hiểu cơ chế tái chế của listview.

Tôi cũng hiểu rằng từ người xem, chúng tôi có thể giữ chế độ xem con trong bộ điều hợp và chúng tôi không phải gọi số findViewById() nhiều lần. Vì vậy, nó là để tối ưu hóa.

Nhưng tôi chỉ có sự nhầm lẫn trong các phương thức setTag(holder)getTag(). From this question, tôi biết rằng để tạo cặp khóa-giá trị trên nhiều đối tượng, để chúng tôi có thể truy cập chúng dễ dàng. Nhưng, tôi không hiểu tại sao họ được yêu cầu ở đây ... bởi vì, chúng tôi không có nhiều đối tượng giữ ... chỉ chúng tôi phải thay đổi các biến của chủ sở hữu mỗi lần. chúng ta có thể viết mã ở đây mà không cần sử dụng setTaggetTag?

ai cũng có thể giải thích rõ hơn rằng những gì setTaggetTag làm "ở đây"?

+0

xin vui lòng không đánh dấu là trùng lặp ... Tôi đã thấy rất nhiều câu trả lời nhưng không thể tìm thấy quyền cho tình huống cụ thể. – xyz

+1

tại sao không thử nó theo cách của bạn và xem kết quả là gì? – panini

+0

Tôi đã thử ... Tôi chưa đặt câu hỏi mà không có bất kỳ thử .. Nếu bạn biết, sau đó xin vui lòng cho câu trả lời – xyz

Trả lời

21

tag là cơ chế để làm cho số views của bạn ghi nhớ điều gì đó, có thể là object một integer một string hoặc bất kỳ thứ gì bạn thích.

vì vậy khi ListView của bạn sẽ tạo lần đầu tiên, convertViewnull. do đó, bạn tạo một convertView mới và đặt tất cả references của số objects của số row vào một số viewHolder. sau đó lưu viewHolder vào bộ nhớ của bạn convertView (setTag). Android mất convertView của bạn và đặt nó trong pool đến recycle nó và passes lại một lần nữa cho bạn. nhưng số pool của nó có thể không đủ convertViews để nó lại vượt qua convertView thats null mới. do đó, một lần nữa câu chuyện được lặp lại cho đến khi pool của android được lấp đầy. sau đó android mất một convertView từ hồ bơi của nó và chuyển nó cho bạn. bạn sẽ thấy rằng nó không phải là null vì vậy bạn hỏi nó ở đâu là đối tượng của tôi references mà tôi đã cung cấp cho bạn lần đầu tiên? (getTag) vì vậy bạn sẽ nhận được chúng và làm bất cứ điều gì bạn thích.

More xây dựng trên dòng dưới đây

but its pool may not have enough convertViews so it again passes a new convertView thats null

android pool trống khi listView của bạn sẽ tạo ra. do đó, đối với mục đầu tiên của số listView, nó sẽ gửi cho bạn convertView phải được hiển thị. sau đó android lưu nó trong số pool, vì vậy pool hiện chỉ chứa một convertView. cho mục thứ hai của bạn trong số listView sẽ tạo android không thể sử dụng nhóm của nó vì nó thực sự có một phần tử và phần tử đó là mục đầu tiên của bạn và nó đang được hiển thị ngay bây giờ để nó vượt qua convertView khác. quá trình này lặp lại cho đến khi android tìm thấy một số convertView trong số pool hiện không được hiển thị và chuyển cho bạn.

Android thổi phồng mỗi hàng cho đến khi màn hình được lấp đầy sau đó khi bạn cuộn danh sách, nó sử dụng chủ.

+0

cảm ơn nhưng tôi không hiểu điều này: "nhưng hồ bơi của nó có thể không có đủ convertViews để nó lại vượt qua một biến đổi mới thats null" - sau đó trong tình huống đó, nó có thể không có đủ chuyển đổi? – xyz

+0

cập nhật lại, hãy xem lại nó – mmlooloo

+0

cảm ơn ...Tóm lại, Android phải thổi phồng bố cục của hàng mới cho đến khi bố cục phù hợp với kích thước màn hình. sau hơn nó sử dụng chủ sở hữu để thay đổi chế độ xem con trong hàng. đúng? – xyz

2

Nhưng, tôi không hiểu tại sao họ được yêu cầu ở đây ... bởi vì, chúng tôi không có nhiều người giữ các đối tượng

Đây là nơi bạn là sai - có một người giữ cho mỗi lần xem (aka mục ListView có thể nhìn thấy hoặc được lưu trữ).

+0

bạn có thể giải thích chi tiết hơn không? – xyz

+1

Có một 'Chủ giữ thời tiết' riêng biệt cho mỗi chế độ xem. –

+0

@ShivamVerma ý của bạn là - đối với mỗi hàng. đúng? – xyz

14

Hãy Nhìn vào một quan niệm khác nhau:

enter image description here

Hãy tưởng tượng rằng các trực thăng là "hàng" trong khi dây là "setTag" và xe bên dưới là "WeatherHolder", nhưng phi công của Máy bay trực thăng ở trong xe đó và người đó là người quản lý contro lling máy bay trực thăng bằng cách sử dụng một "WIRED REMOTE".

Khi bạn cắt dây thừng là "setTag" Hellicopter vẫn bay nhưng phi công không còn có thể điều khiển nó vì phi công rơi xuống đất nghĩa là phi công giờ đã chết! (Trong java khi một đối tượng mất tham chiếu của nó, Garbage Collector sẽ thu thập và giải phóng bộ nhớ đó).

Khi bạn không đặt hoặc gắn dây vào xe trong khi máy bay trực thăng sắp bay nơi Phi công đang ngồi - bạn có khả năng mất kiểm soát trên trực thăng vì bạn đang sử dụng "WIRED REMOTE".

Tôi hy vọng sự trợ giúp này :).

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