32
阿裏雲
技術社區[雲棲]
ViewHolder模式超簡潔寫法,很cool!
轉自https://www.eoeandroid.com/forum.php?mod=viewthread&tid=321547&page=3#pid3555274
ViewHolder是什麼就不解釋了。
大家通常怎麼寫ViewHolder呢?
01 |
ViewHolder holder = null ;
|
02 |
if (convertView == null ){
|
03 |
convertView = mInflater.inflate(R.layout.xxx null );
|
04 |
holder = new
ViewHolder();
|
05 |
holder.tvXXX = (TextView)findViewById(R.id.xxx);
|
09 |
holder = (ViewHolder) convertView.getTag();
|
14 |
private static
class ViewHolder{
|
這麼寫一次還行,但問題是總有很多很多的ViewAdapter要這麼寫,每次都repeat,repeat,repeat 累啊。 所以,有這麼一種簡潔的寫法分享給大家,先聲明,從國外網站上看的,不是自己原創的,但確實很喜歡這個簡潔的設計。
ViewHolder這麼寫(隻提供一個靜態方法,其實可以加一個私有構造函數防止外部實例化),代碼很簡單,看過就明白了
01 |
public class ViewHolder {
|
02 |
// I added a generic return type to reduce the casting noise in client code
|
03 |
@SuppressWarnings ( "unchecked" )
|
04 |
public static
<T extends View> T get(View view,
int id) {
|
05 |
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
|
06 |
if (viewHolder ==
null ) {
|
07 |
viewHolder = new
SparseArray<View>();
|
08 |
view.setTag(viewHolder);
|
10 |
View childView = viewHolder.get(id);
|
11 |
if (childView ==
null ) {
|
12 |
childView = view.findViewById(id);
|
13 |
viewHolder.put(id, childView);
|
在getView裏這樣
02 |
public View getView( int position, View convertView, ViewGroup parent) {
|
04 |
if (convertView ==
null ) {
|
05 |
convertView = LayoutInflater.from(context)
|
06 |
.inflate(R.layout.banana_phone, parent, false );
|
09 |
ImageView bananaView = ViewHolder.get(convertView, R.id.banana);
|
10 |
TextView phoneView = ViewHolder.get(convertView, R.id.phone);
|
12 |
BananaPhone bananaPhone = getItem(position);
|
13 |
phoneView.setText(bananaPhone.getPhone());
|
14 |
bananaView.setImageResource(bananaPhone.getBanana());
|
哈哈,完成了,果斷把這個ViewHolder類加入自己的utils,一勞永逸了以後~
值得注意的是SparseArray這個知識點,優化過的存儲integer和object鍵值對的hashmap,網上資料很多這裏就不廢話了~
其實這種寫法本質和ViewHolder Partten沒有什麼不同,ViewHolder Partten是把一個自定義類綁定到一個view,這種是把SparseArray綁定到一個view,雖然SparseArray 初始化會分配10長度的地址,理論上貌似浪費了內存,理論上插入和刪除操作也是有時間損耗的,但是這些都在允許範圍內。
比如https://github.com/JoanZapata/base-adapter-helper 作者也說了他做了大量測試,這種損耗微乎其微。
再次,萬一萬一因特殊情況發現了有性能瓶頸,到時候再優化就可以了,但是絕大多數場合都是可以使用的,大量簡化你的開發,加快開發速度,代碼少了,出錯的幾率就小了,維護的成本也小了~好處還是大大的。
簡單的紙上分析~:
(1)ViewHolder Pattern是每一個View一個ViewHolder,裏麵是記錄listitem內控件引用; SparseArray是記錄id和控件引用的鍵值對,當然SparseArray初始化會分配一定地址空間(默認是10),但是這些內存損耗應該是可以忽略的~
(2)SparseArray是優化過的int-object的hashmap,使用折半查找,並優化了內存分配,所以代碼執行成本通常是可控的。
綜上,使用SparseArray與ViewHolder相比是有損耗,但應該是可控的。使用SparseArray優點是加快開發速度和減少代碼維護,當發現有性能瓶頸時,再進行優化~
最後更新:2017-04-03 06:03:03