通用的ListView GridView適配器


1、概述

相信做Android開發的寫得最多的就是ListView,GridView的適配器吧,記得以前開發一同事開發項目,一個項目下來基本就一直在寫ListView的Adapter都快吐了~~~對於Adapter一般都繼承BaseAdapter複寫幾個方法,getView裏面使用ViewHolder模式,其實大部分的代碼基本都是類似的。

本篇博客爲快速開發系列的第一篇,將一步一步帶您封裝出一個通用的Adapter。

2、常見的例子

首先看一個最常見的案例,大家一目十行的掃一眼

1、佈局文件

主佈局文件:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <ListView  
  7.         android:id="@+id/id_lv_main"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent" />  
  10.   
  11. </RelativeLayout>  

Item的佈局文件:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/id_tv_title"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="50dp"  
  6.     android:background="#aa111111"  
  7.     android:gravity="center_vertical"  
  8.     android:paddingLeft="15dp"  
  9.     android:textColor="#ffffff"  
  10.     android:text="hello"  
  11.     android:textSize="20sp"  
  12.     android:textStyle="bold" >  
  13.   
  14. </TextView>  

2、Adapter

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.TextView;  
  11.   
  12. public class MyAdapter extends BaseAdapter  
  13. {  
  14.     private LayoutInflater mInflater;  
  15.     private Context mContext;  
  16.     private List<String> mDatas;  
  17.   
  18.     public MyAdapter(Context context, List<String> mDatas)  
  19.     {  
  20.         mInflater = LayoutInflater.from(context);  
  21.         this.mContext = context;  
  22.         this.mDatas = mDatas;  
  23.     }  
  24.   
  25.     @Override  
  26.     public int getCount()  
  27.     {  
  28.         return mDatas.size();  
  29.     }  
  30.   
  31.     @Override  
  32.     public Object getItem(int position)  
  33.     {  
  34.         return mDatas.get(position);  
  35.     }  
  36.   
  37.     @Override  
  38.     public long getItemId(int position)  
  39.     {  
  40.         return position;  
  41.     }  
  42.   
  43.     @Override  
  44.     public View getView(int position, View convertView, ViewGroup parent)  
  45.     {  
  46.         ViewHolder viewHolder = null;  
  47.         if (convertView == null)  
  48.         {  
  49.             convertView = mInflater.inflate(R.layout.item_single_str, parent,  
  50.                     false);  
  51.             viewHolder = new ViewHolder();  
  52.             viewHolder.mTextView = (TextView) convertView  
  53.                     .findViewById(R.id.id_tv_title);  
  54.             convertView.setTag(viewHolder);  
  55.         } else  
  56.         {  
  57.             viewHolder = (ViewHolder) convertView.getTag();  
  58.         }  
  59.         viewHolder.mTextView.setText(mDatas.get(position));  
  60.         return convertView;  
  61.     }  
  62.   
  63.     private final class ViewHolder  
  64.     {  
  65.         TextView mTextView;  
  66.     }  
  67.   
  68. }  

3、Activity

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.widget.ListView;  
  10.   
  11. public class MainActivity extends Activity  
  12. {  
  13.   
  14.     private ListView mListView;  
  15.     private List<String> mDatas = new ArrayList<String>(Arrays.asList("Hello",  
  16.             "World""Welcome"));  
  17.     private MyAdapter mAdapter;  
  18.   
  19.     @Override  
  20.     protected void onCreate(Bundle savedInstanceState)  
  21.     {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.activity_main);  
  24.         mListView = (ListView) findViewById(R.id.id_lv_main);  
  25.         mListView.setAdapter(mAdapter = new MyAdapter(this, mDatas));  
  26.   
  27.     }  
  28.   
  29. }  

上面這個例子大家應該都寫了無數遍了,MyAdapter集成BaseAdapter,然後getView裏面使用ViewHolder模式;一般情況下,我們的寫法是這樣的:對於不同佈局的ListView,我們會有一個對應的Adapter,在Adapter中又會有一個ViewHolder類來提高效率。

這樣出現ListView就會出現與之對於的Adapter類、ViewHolder類;那麼有沒有辦法減少我們的編碼呢?

下面首先拿ViewHolder開刀~

3、通用的ViewHolder

首先分析下ViewHolder的作用,通過convertView.setTag與convertView進行綁定,然後當convertView複用時,直接從與之對於的ViewHolder(getTag)中拿到convertView佈局中的控件,省去了findViewById的時間~

也就是說,實際上們每個convertView會綁定一個ViewHolder對象,這個viewHolder主要用於幫convertView存儲佈局中的控件。

那麼我們只要寫出一個通用的ViewHolder,然後對於任意的convertView,提供一個對象讓其setTag即可;

既然是通用,那麼我們這個ViewHolder就不可能含有各種控件的成員變量了,因爲每個Item的佈局是不同的,最好的方式是什麼呢?

提供一個容器,專門存每個Item佈局中的所有控件,而且還要能夠查找出來;既然需要查找,那麼ListView肯定是不行了,需要一個鍵值對進行保存,鍵爲控件的Id,值爲控件的引用,相信大家立刻就能想到Map;但是我們不用Map,因爲有更好的替代類,就是我們android提供的SparseArray這個類,和Map類似,但是比Map效率,不過鍵只能爲Integer.

下面看我們的ViewHolder類:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import android.content.Context;  
  4. import android.util.Log;  
  5. import android.util.SparseArray;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9.   
  10. public class ViewHolder  
  11. {  
  12.     private final SparseArray<View> mViews;  
  13.     private View mConvertView;  
  14.   
  15.     private ViewHolder(Context context, ViewGroup parent, int layoutId,  
  16.             int position)  
  17.     {  
  18.         this.mViews = new SparseArray<View>();  
  19.         mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,  
  20.                 false);  
  21.         //setTag  
  22.         mConvertView.setTag(this);  
  23.           
  24.           
  25.     }  
  26.   
  27.     /** 
  28.      * 拿到一個ViewHolder對象 
  29.      * @param context 
  30.      * @param convertView 
  31.      * @param parent 
  32.      * @param layoutId 
  33.      * @param position 
  34.      * @return 
  35.      */  
  36.     public static ViewHolder get(Context context, View convertView,  
  37.             ViewGroup parent, int layoutId, int position)  
  38.     {  
  39.       
  40.         if (convertView == null)  
  41.         {  
  42.             return new ViewHolder(context, parent, layoutId, position);  
  43.         }  
  44.         return (ViewHolder) convertView.getTag();  
  45.     }  
  46.   
  47.   
  48.     /** 
  49.      * 通過控件的Id獲取對於的控件,如果沒有則加入views 
  50.      * @param viewId 
  51.      * @return 
  52.      */  
  53.     public <T extends View> T getView(int viewId)  
  54.     {  
  55.           
  56.         View view = mViews.get(viewId);  
  57.         if (view == null)  
  58.         {  
  59.             view = mConvertView.findViewById(viewId);  
  60.             mViews.put(viewId, view);  
  61.         }  
  62.         return (T) view;  
  63.     }  
  64.   
  65.     public View getConvertView()  
  66.     {  
  67.         return mConvertView;  
  68.     }  
  69.   
  70.       
  71.   
  72. }  


與傳統的ViewHolder不同,我們使用了一個SparseArray<View>用於存儲與之對於的convertView的所有的控件,當需要拿這些控件時,通過getView(id)進行獲取;

下面看使用該ViewHolder的MyAdapter;

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. @Override  
  2.     public View getView(int position, View convertView, ViewGroup parent)  
  3.     {  
  4.         //實例化一個viewHolder  
  5.         ViewHolder viewHolder = ViewHolder.get(mContext, convertView, parent,  
  6.                 R.layout.item_single_str, position);  
  7.         //通過getView獲取控件  
  8.         TextView tv = viewHolder.getView(R.id.id_tv_title);  
  9.         //使用  
  10.         tv.setText(mDatas.get(position));  
  11.         return viewHolder.getConvertView();  
  12.     }  

只看getView,其他方法都一樣;首先調用ViewHolder的get方法,如果convertView爲null,new一個ViewHolder實例,通過使用mInflater.inflate加載佈局,然後new一個SparseArray用於存儲View,最後setTag(this);

如果存在那麼直接getTag

最後通過getView(id)獲取控件,如果存在則直接返回,否則調用findViewById,返回存儲,返回。

好了,一個通用的ViewHolder寫好了,以後一個項目幾十個Adapter一個ViewHolder直接hold住全場~~大家可以省點時間鬥個小地主了~~

4、打造通用的Adapter

有了通用的ViewHolder大家肯定不能滿足,怎麼也得省出dota的時間,人在塔在~~

下面看如何打造一個通過的Adapter,我們叫做CommonAdapter

繼續分析,Adapter一般需要保持一個List對象,存儲一個Bean的集合,不同的ListView,Bean肯定是不同的,這個CommonAdapter肯定需要支持泛型,內部維持一個List<T>,就解決我們的問題了;

於是我們初步打造我們的CommonAdapter

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.TextView;  
  11.   
  12. public abstract class CommonAdapter<T> extends BaseAdapter  
  13. {  
  14.     protected LayoutInflater mInflater;  
  15.     protected Context mContext;  
  16.     protected List<T> mDatas;  
  17.   
  18.     public CommonAdapter(Context context, List<T> mDatas)  
  19.     {  
  20.         mInflater = LayoutInflater.from(context);  
  21.         this.mContext = context;  
  22.         this.mDatas = mDatas;  
  23.     }  
  24.   
  25.     @Override  
  26.     public int getCount()  
  27.     {  
  28.         return mDatas.size();  
  29.     }  
  30.   
  31.     @Override  
  32.     public Object getItem(int position)  
  33.     {  
  34.         return mDatas.get(position);  
  35.     }  
  36.   
  37.     @Override  
  38.     public long getItemId(int position)  
  39.     {  
  40.         return position;  
  41.     }  
  42.   
  43. }  
我們的CommonAdapter依然是一個抽象類,除了getView以外我們把其他的代碼都實現了,這樣的話,在使用我們的Adapter只要實現一個getView,然後getView裏面再使用我們打造的通過的ViewHolder是不是感覺還不錯~

現在我們的MyAdapter是這樣的:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.TextView;  
  9.   
  10. public class MyAdapter<T> extends CommonAdapter<T>  
  11. {  
  12.     public MyAdapter(Context context, List<T> mDatas)  
  13.     {  
  14.         super(context, mDatas);  
  15.     }  
  16.   
  17.     @Override  
  18.     public View getView(int position, View convertView, ViewGroup parent)  
  19.     {  
  20.         ViewHolder viewHolder = ViewHolder.get(mContext, convertView, parent,  
  21.                 R.layout.item_single_str, position);  
  22.         TextView mTitle = viewHolder.getView(R.id.id_tv_title);  
  23.         mTitle.setText((String) mDatas.get(position));  
  24.         return viewHolder.getConvertView();  
  25.     }  
  26.   
  27. }  

所有的代碼加起來也就10行左右,是不是神清氣爽~~稍等,我先去dota一把~

但是我們是否就這樣滿足了呢?顯然還可以簡化。

5、進一步鑄造

注意我們的getView裏面的代碼,雖然只有4行,但是我覺得所有的Adapter的

第一行(ViewHolder viewHolder = getViewHolder(position, convertView,parent);)和

最後一行:return viewHolder.getConvertView();一定是一樣的。

那麼我們可以這樣做:我們把第一行和最後一行寫死,把中間變化的部分抽取出來,這不就是OO的設計原則嘛。現在CommonAdapter是這樣的:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.BaseAdapter;  
  10.   
  11. public abstract class CommonAdapter<T> extends BaseAdapter  
  12. {  
  13.     protected LayoutInflater mInflater;  
  14.     protected Context mContext;  
  15.     protected List<T> mDatas;  
  16.     protected final int mItemLayoutId;  
  17.   
  18.     public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId)  
  19.     {  
  20.         this.mContext = context;  
  21.         this.mInflater = LayoutInflater.from(mContext);  
  22.         this.mDatas = mDatas;  
  23.         this.mItemLayoutId = itemLayoutId;  
  24.     }  
  25.   
  26.     @Override  
  27.     public int getCount()  
  28.     {  
  29.         return mDatas.size();  
  30.     }  
  31.   
  32.     @Override  
  33.     public T getItem(int position)  
  34.     {  
  35.         return mDatas.get(position);  
  36.     }  
  37.   
  38.     @Override  
  39.     public long getItemId(int position)  
  40.     {  
  41.         return position;  
  42.     }  
  43.   
  44.     @Override  
  45.     public View getView(int position, View convertView, ViewGroup parent)  
  46.     {  
  47.         final ViewHolder viewHolder = getViewHolder(position, convertView,  
  48.                 parent);  
  49.         convert(viewHolder, getItem(position));  
  50.         return viewHolder.getConvertView();  
  51.   
  52.     }  
  53.   
  54.     public abstract void convert(ViewHolder helper, T item);  
  55.   
  56.     private ViewHolder getViewHolder(int position, View convertView,  
  57.             ViewGroup parent)  
  58.     {  
  59.         return ViewHolder.get(mContext, convertView, parent, mItemLayoutId,  
  60.                 position);  
  61.     }  
  62.   
  63. }  

對外公佈了一個convert方法,並且還把viewHolder和本Item對於的Bean對象給傳出去,現在convert方法裏面需要幹嘛呢?

通過ViewHolder把View找到,通過Item設置值;

現在我覺得代碼簡化到這樣,我已經不需要單獨寫一個Adapter了,直接MainActivity匿名內部類走起~

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. @Override  
  2.     protected void onCreate(Bundle savedInstanceState)  
  3.     {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.activity_main);  
  6.         mListView = (ListView) findViewById(R.id.id_lv_main);  
  7.   
  8.         //設置適配器  
  9.         mListView.setAdapter(mAdapter = new CommonAdapter<String>(  
  10.                 getApplicationContext(), mDatas, R.layout.item_single_str)  
  11.         {  
  12.             @Override  
  13.             public void convert(ViewHolder c, String item)  
  14.             {  
  15.                 TextView view = viewHolder.getView(R.id.id_tv_title);  
  16.                 view.setText(item);  
  17.             }  
  18.   
  19.         });  
  20.   
  21.     }  

可以看到效果咋樣,不錯吧。你覺得還能簡化麼?我覺得還能改善。

6、Adapter最後的封魔

我們現在在convertView裏面需要這樣:

@Override
public void convert(ViewHolder viewHolder, String item)
{
TextView view = viewHolder.getView(R.id.id_tv_title);
view.setText(item);
}

我們細想一下,其實佈局裏面的View常用也就那麼幾種:ImageView,TextView,Button,CheckBox等等;

那麼我覺得ViewHolder還可以封裝一些常用的方法,比如setText(id,String);setImageResource(viewId, resId);setImageBitmap(viewId, bitmap);

那麼現在ViewHolder是:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.zhy_baseadapterhelper;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.util.SparseArray;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.ImageView;  
  10. import android.widget.TextView;  
  11.   
  12. import com.example.zhy_baseadapterhelper.ImageLoader.Type;  
  13.   
  14. public class ViewHolder  
  15. {  
  16.     private final SparseArray<View> mViews;  
  17.     private int mPosition;  
  18.     private View mConvertView;  
  19.   
  20.     private ViewHolder(Context context, ViewGroup parent, int layoutId,  
  21.             int position)  
  22.     {  
  23.         this.mPosition = position;  
  24.         this.mViews = new SparseArray<View>();  
  25.         mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,  
  26.                 false);  
  27.         // setTag  
  28.         mConvertView.setTag(this);  
  29.     }  
  30.   
  31.     /** 
  32.      * 拿到一個ViewHolder對象 
  33.      *  
  34.      * @param context 
  35.      * @param convertView 
  36.      * @param parent 
  37.      * @param layoutId 
  38.      * @param position 
  39.      * @return 
  40.      */  
  41.     public static ViewHolder get(Context context, View convertView,  
  42.             ViewGroup parent, int layoutId, int position)  
  43.     {  
  44.         if (convertView == null)  
  45.         {  
  46.             return new ViewHolder(context, parent, layoutId, position);  
  47.         }  
  48.         return (ViewHolder) convertView.getTag();  
  49.     }  
  50.   
  51.     public View getConvertView()  
  52.     {  
  53.         return mConvertView;  
  54.     }  
  55.   
  56.     /** 
  57.      * 通過控件的Id獲取對於的控件,如果沒有則加入views 
  58.      *  
  59.      * @param viewId 
  60.      * @return 
  61.      */  
  62.     public <T extends View> T getView(int viewId)  
  63.     {  
  64.         View view = mViews.get(viewId);  
  65.         if (view == null)  
  66.         {  
  67.             view = mConvertView.findViewById(viewId);  
  68.             mViews.put(viewId, view);  
  69.         }  
  70.         return (T) view;  
  71.     }  
  72.   
  73.     /** 
  74.      * 爲TextView設置字符串 
  75.      *  
  76.      * @param viewId 
  77.      * @param text 
  78.      * @return 
  79.      */  
  80.     public ViewHolder setText(int viewId, String text)  
  81.     {  
  82.         TextView view = getView(viewId);  
  83.         view.setText(text);  
  84.         return this;  
  85.     }  
  86.   
  87.     /** 
  88.      * 爲ImageView設置圖片 
  89.      *  
  90.      * @param viewId 
  91.      * @param drawableId 
  92.      * @return 
  93.      */  
  94.     public ViewHolder setImageResource(int viewId, int drawableId)  
  95.     {  
  96.         ImageView view = getView(viewId);  
  97.         view.setImageResource(drawableId);  
  98.   
  99.         return this;  
  100.     }  
  101.   
  102.     /** 
  103.      * 爲ImageView設置圖片 
  104.      *  
  105.      * @param viewId 
  106.      * @param drawableId 
  107.      * @return 
  108.      */  
  109.     public ViewHolder setImageBitmap(int viewId, Bitmap bm)  
  110.     {  
  111.         ImageView view = getView(viewId);  
  112.         view.setImageBitmap(bm);  
  113.         return this;  
  114.     }  
  115.   
  116.     /** 
  117.      * 爲ImageView設置圖片 
  118.      *  
  119.      * @param viewId 
  120.      * @param drawableId 
  121.      * @return 
  122.      */  
  123.     public ViewHolder setImageByUrl(int viewId, String url)  
  124.     {  
  125.         ImageLoader.getInstance(3, Type.LIFO).loadImage(url,  
  126.                 (ImageView) getView(viewId));  
  127.         return this;  
  128.     }  
  129.   
  130.     public int getPosition()  
  131.     {  
  132.         return mPosition;  
  133.     }  
  134.   
  135. }  

現在的MainActivity只需要這麼寫:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mAdapter = new CommonAdapter<String>(getApplicationContext(),  
  2.                 R.layout.item_single_str, mDatas)  
  3.         {  
  4.             @Override  
  5.             protected void convert(ViewHolder viewHolder, String item)  
  6.             {  
  7.                 viewHolder.setText(R.id.id_tv_title, item);  
  8.             }  
  9.         };  

convertView裏面只要一行代碼了~~~

好了,到此我們的通用的Adapter已經一步一步鑄造完畢~咋樣,以後寫項目省下來的時間是不是可以陪我切磋dota了(ps:11暱稱:血魔哥404)~~

注:關於ViewHolder裏面的setText,setImageResource這類的方法,大家可以在使用的過程中不斷的完善,今天發現這個控件可以這麼設置值,好,放進去;時間長了,基本就完善了。還有那個ImageLoader是我另一篇博客裏的,大家可以使用UIL,Volley或者自己寫個圖片加載器;

7、實踐

說了這麼多,還是得拿出來讓我們的實踐檢驗檢驗,順便來幾張套圖,俗話說,沒圖沒正相。

1、我們的實例代碼的圖是這樣的:

關於Adapter和ViewHolder的代碼是這樣的:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. // 設置適配器  
  2.         mListView.setAdapter(mAdapter = new CommonAdapter<String>(  
  3.                 getApplicationContext(), mDatas, R.layout.item_single_str)  
  4.         {  
  5.             @Override  
  6.             public void convert(ViewHolder helper, String item)  
  7.             {  
  8.                 helper.setText(R.id.id_tv_title,item);  
  9.             }  
  10.   
  11.         });  

哎喲,我是不是隻要貼一行;

2、來個複雜點的佈局

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="#ffffff"  
  6.     android:orientation="vertical"  
  7.     android:padding="10dp" >  
  8.   
  9.     <TextView  
  10.         android:id="@+id/tv_title"  
  11.         android:layout_width="match_parent"  
  12.         android:layout_height="wrap_content"  
  13.         android:singleLine="true"  
  14.         android:text="紅色錢包"  
  15.         android:textSize="16sp"  
  16.         android:textColor="#444444" >  
  17.     </TextView>  
  18.   
  19.     <TextView  
  20.         android:id="@+id/tv_describe"  
  21.         android:layout_width="match_parent"  
  22.         android:layout_height="wrap_content"  
  23.         android:layout_below="@id/tv_title"  
  24.         android:layout_marginTop="10dp"  
  25.         android:maxLines="2"  
  26.         android:minLines="1"  
  27.         android:text="週三早上丟失了紅色錢包,在食堂二樓"  
  28.         android:textColor="#898989"  
  29.         android:textSize="16sp" >  
  30.     </TextView>  
  31.   
  32.     <TextView  
  33.         android:id="@+id/tv_time"  
  34.         android:layout_width="wrap_content"  
  35.         android:layout_height="wrap_content"  
  36.         android:layout_below="@id/tv_describe"  
  37.         android:layout_marginTop="10dp"  
  38.         android:text="20130240122"  
  39.         android:textColor="#898989"  
  40.         android:textSize="12sp" >  
  41.     </TextView>  
  42.   
  43.     <TextView  
  44.         android:id="@+id/tv_phone"  
  45.         android:layout_width="wrap_content"  
  46.         android:layout_height="wrap_content"  
  47.         android:layout_alignParentRight="true"  
  48.         android:layout_below="@id/tv_describe"  
  49.         android:layout_marginTop="10dp"  
  50.         android:background="#5cbe6c"  
  51.         android:drawableLeft="@drawable/icon_photo"  
  52.         android:drawablePadding="5dp"  
  53.         android:paddingBottom="3dp"  
  54.         android:paddingLeft="5dp"  
  55.         android:paddingRight="5dp"  
  56.         android:paddingTop="3dp"  
  57.         android:text="138024249542"  
  58.         android:textColor="#ffffff"  
  59.         android:textSize="12sp" >  
  60.     </TextView>  
  61.   
  62. </RelativeLayout>  

效果圖是這樣的:


佈局是不是挺複雜的了~~

但是代碼是這樣的:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. // 設置適配器  
  2.         mListView.setAdapter(mAdapter = new CommonAdapter<Bean>(  
  3.                 getApplicationContext(), mDatas, R.layout.item_list)  
  4.         {  
  5.             @Override  
  6.             public void convert(ViewHolder helper, Bean item)  
  7.             {  
  8.                 helper.setText(R.id.tv_title, item.getTitle());  
  9.                 helper.setText(R.id.tv_describe, item.getDesc());  
  10.                 helper.setText(R.id.tv_phone, item.getPhone());  
  11.                 helper.setText(R.id.tv_time, item.getTime());  
  12.                   
  13. //              helper.getView(R.id.tv_title).setOnClickListener(l)  
  14.             }  
  15.   
  16.         });  

從一個字符串的佈局到這樣的佈局,Adapter加ViewHolder的改變就這麼多,加起來3行左右代碼~~~


到此,Android 快速開發系列 打造萬能的ListView GridView 適配器結束;


最後給大家推薦一個gitHub項目:https://github.com/JoanZapata/base-adapter-helper ,這個項目所做的,和我上面寫的基本一致。

還有上面的佈局文件來自網絡,感謝Bmob的提供~

好了,我要去快樂的玩耍了~~


源碼點擊下載:http://download.csdn.net/detail/lmj623565791/7836429


原文地址:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自【張鴻洋的博客】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章