2011-05-19 104 views
4

任何人都可以請解釋兩種getView()實現之間有什麼區別嗎?這兩種getView()的實現有什麼區別?

第一個檢查convertView是否爲空;如果它爲null,則膨脹一個新的View對象。然後設置適當的值的子視圖。

@Override 
public View getView(int position, View convertView, ViewGroup parent) 
{   
    if(convertView == null) 
    { 
     LayoutInflater inflater = context.getLayoutInflater(); 
     convertView = inflater.inflate(R.layout.itemlayout, null, true); 
    } 

    ImageView image = (ImageView) convertView.findViewById(R.id.icon); 
    TextView text = (TextView) convertView.findViewById(R.id.name);  

    MyItem item = items[position]; 
    text.setText(item.name); 
    if("male".equals(item.gender)) 
    { 
     image.setImageResource(R.drawable.male); 
    } 
    else if("female".equals(item.gender)) 
    { 
     image.setImageResource(R.drawable.female); 
    } 

    return convertView; 
} 

第二個是所謂的「ViewHolder」模式。許多開發人員說這種方法可以節省大量的內存和CPU時間。但是第一個實現也檢查了convertView的存在。第一種方法不是保存一些內存嗎?任何人都可以更深入,更清楚地解釋兩種實現之間的區別嗎?非常感謝。

@Override 
public View getView(int position, View convertView, ViewGroup parent) 
{  
    ViewHolder holder; 

    View itemView = convertView; 
    if(itemView == null) 
    { 
     LayoutInflater inflater = context.getLayoutInflater(); 
     itemView = inflater.inflate(R.layout.itemlayout, null, true); 
     holder = new ViewHolder(); 
     holder.image = (ImageView) itemView.findViewById(R.id.icon); 
     holder.text = (TextView) itemView.findViewById(R.id.name); 
     itemView.setTag(holder); 
    } 
    else 
    { 
     holder = (ViewHolder) itemView.getTag(); 
    } 

    MyItem item = items[position]; 
    holder.text.setText(item.name); 
    if("male".equals(item.gender)) 
    { 
     holder.image.setImageResource(R.drawable.male); 
    } 
    else if("female".equals(item.gender)) 
    { 
     holder.image.setImageResource(R.drawable.female); 
    } 

    return itemView; 
} 

回答

5

第二圖案創建ViewHolder的靜態實例,並將其附加到該視圖項目它裝在第一時間,然後將它從上將來該視圖標籤中檢索呼叫

getView ()被非常頻繁地調用,特別是當你滾動列表中的大元素時,實際上每當列表視圖項在滾動中變得可見時就會調用它。

這可以防止調用findViewById()很多次無用,保留一個靜態引用的視圖,這是一個很好的模式來保存一些資源(尤其是當你需要引用你的列表視圖項目中的許多視圖)。

+1

這不僅僅是findViewById(),儘管它是最常見的用例。 ViewHolder可以也應該用來存儲臨時數據結構,以避免getView()中的內存分配。一個很好的例子可以在這裏找到:http://goo.gl/NzgTt和http://goo.gl/d4vvo ViewHolder包含一個字符緩衝區,以避免從光標獲取數據時的分配。 – 2011-05-19 16:30:40

+1

相關提示=) – BFil 2011-05-19 17:19:13

1

使用viewHolder可防止每次需要在屏幕上綁定視圖時調用findviewById()。這意味着視圖膨脹了,連接到它的資源只被初始化一次(通脹,findById,監聽器,不會像靜態標題或其他內容那樣改變的內容)。所以使用這種方法在使用列表的時候可以獲得更好的性能,因此也就是始終推薦的方法