基本上我的部落格是根據我手頭的項目來寫,如有不對的地方,希望大家能給樓主指出來,在此先道聲謝謝!
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5CanVXYs9CX0xWdhZWZk9CX09Wbl9lcvRXakVGa49CXy9GdpRWZoh3LcRXZu5ibkN3Yuc2bsJmLjlGdhR3cvw1LcpDc0RHaiojIsJye.gif)
android項目中需要制作一個類似于youtube的視訊清單的界面,可采用ListView的方式實作,listView實作最好的方法就是配合Adapter(擴充卡)為其添資料,當然直接在java代碼中為其添加資料也可以,但是不能實作動态資料的添加,比如說擷取web伺服器或者是其他程式中的資料。
關于Adapter:我們經常用"Men in the middle"中句話來描述它,也 就是“中間者”的意思。可以将它了解成資料和UI(View)之間的一個橋梁。
listview下的常用的adapter有:SimpleAdapter,ArrayAdapter,BaseAdapter等,其中我覺得最實用的就是BaseAdapter啦~
然後我們詳細講下這個。
BaseAdapter是個抽象類,繼承它需要實作的方法有:
getCount(), getItem(int position),
getItemId(int position),
getView(int position, View convertView, ViewGroup parent)
首先通過代碼來簡單介紹下:
class MyImgAdapter extends BaseAdapter {
@Override
public int getCount() {
// 根據他的傳回值得到 listView的長度
return 0;
}
@Override
public Object getItem(int position) {
// 傳回目前Item顯示的資料,友善在Activity中的onItemClick方法中調用
return null;
}
@Override
public long getItemId(int position) {
// 長按傳回目前Item顯示的資料,友善在Activity中的onItemClick方法中調用
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// position就是位置從0開始,convertView是ListView中每一項要顯示的view
// 通常return 的view也就是convertView
// parent就是父窗體了,也就是ListView了.
return null;
}
可能還有些小盆于看不明白,不要着急,看了下面的解釋你就明白了
ListView繪制的過程如下:
第一步:系統在繪制ListView之前,将會先調用getCount方法來擷取Item的個數。
第二步:開始繪制ListView清單,每繪制一個Item就會調用一次getView方法,在此方法内就可以引用事先定義好的xml來确定顯示的效果并傳回一個View對象作為一個Item顯示出來。也正是在這個過程中完成了擴充卡的主要轉換功能,把資料和資源以開發者想要的效果顯示出來,一行行繪制,直到行數超過getCount()的傳回值。
這兩個方法是自定ListView顯示效果中最為重要的,同時隻要重寫好了就兩個方法,ListView就能完全按開發者的要求顯示。而getItem和getItemId方法将會在調用ListView的響應方法的時候被調用到。是以要保證ListView的各個方法有效的話,這兩個方法也得重寫。比如:沒有完成getItemId方法的功能實作的話,當調用ListView的getItemIdAtPosition()方法時将會得不到想要的結果,因為該方法就是調用了對應的擴充卡的getItemId方法。
接下來我們來寫個簡單的demo來實作下:
為了保證代碼的高效性,以下的代碼用到了一些優化政策,客官老爺們可以放心的直接用到項目中啦!!不過在寫之前大家還需要了解下convertview和viewholder這兩個東東。
convertview:官方解釋是,The old view to reuse, if possible。原理上講就是當ListView滑動的過程中 會有item被滑出螢幕 而不再被使用 這時候Android會回收這個條目的view 這個view也就是這裡的convertView。
ViewHolder:
就是一個持有者的類,他裡面一般沒有方法,隻有屬性,作用就是一個臨時的儲存器,把你getView方法中每次傳回的View存起來,可以下次再用。這樣做的好處就是不必每次都到布局檔案中去拿到你的View,提高了效率。
第一步:建立一個android項目,我的項目名字是BaseAdapterDemo
第二步:修改activity_main.xml檔案
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
第三步:編寫ListView的xml檔案,這裡我隻添加了一個TextView,大家也可以加入其他東西。比如一個清單有可以點選的圖檔(ImageButton),相關資訊的TextView,以及一些Button。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
第四步:編寫MainActivity.java代碼,在onCreate方法下面插入以下代碼
class MyAdapter extends BaseAdapter {
Context mContext;// 用于接收傳遞過來的Context對象
LayoutInflater inflater;
public MyAdapter(Context context) {
mContext = context;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
// 這裡我就傳回8了,也就是一共有8項資料項
return 8;
}
@Override
public Object getItem(int position) {
// 傳回目前Item顯示的資料,友善在Activity中的onItemClick方法中調用
return position;
}
@Override
public long getItemId(int position) {
// 長按傳回目前Item顯示的資料,友善在Activity中的onItemClick方法中調用
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView != null) {
// 當item1被移除螢幕的時候,我們會重新new一個View給新顯示的item 而如果使用了這個convertView
// 我們其實可以複用它,這樣就省去了new View的大量開銷
convertView = inflater.inflate(R.layout.listitem1, parent, false);
viewHolder = new ViewHolder();
viewHolder.textView = (TextView)convertView.findViewById(R.id.textview);
convertView.setTag(viewHolder);
convertView.setTag(viewHolder);
} else {
// 沒有供複用的view 按一般的做法建立view
viewHolder = (ViewHolder) convertView.getTag();
}
//配置每個list的資料
convertView.textView.setText(Integer.toString(position));
return convertView;
}
}
// 定義的ViewHolder,非常簡單,裡面隻有一個TextView
class ViewHolder {
TextView textView;
}
第五步:運作項目就可以看到效果啦。
參考博文:
listview加載性能優化ViewHolder
利用convertView優化ListView性能
如果有問題歡迎郵件交流:我的郵箱[email protected]