Listview控制項不像其他安卓控制項那種直接拖拽到界面上就能用,而是採用類似J2EE中的MVC模型的方式使用,需要通過適配器將某種樣式的數據或控制項添加到其上而使用.MVC模型實現原理是 數據模型M(Model) 存放數據,利用控制器C (Controller)將數據顯示在視圖V (View)上。利用...
Listview控制項不像其他安卓控制項那種直接拖拽到界面上就能用,而是採用類似J2EE中的MVC模型的方式使用,需要通過適配器將某種樣式的數據或控制項添加到其上而使用.
MVC模型實現原理是 數據模型M(Model) 存放數據,利用控制器C (Controller)將數據顯示在視圖V (View)上。
利用BaseAdapter實現一個ListView的步驟一般如下:
1 首先準備好需要顯示在LiseView中的數據 ——List
2 然後編寫2 個XML 文件 第一個文件是ListView控制項所在的佈局文件 第二個文件是ListVIew中每一個item的佈局文件
3 創建一個繼承自BaseAdapter的類
4 為ListView綁定適配器 setAdapter(繼承BaseAdapter 類的實例)
5 用傳統方式來覆寫適配器的getView函數和getCount 函數(從參數convertView里映射佈局文件,find各個控制項填充數據)
6 加入ViewHolder類(定義n個控制項的聲明)用convertView.setTag(viewHolder)在View和Object之間關聯,此目的是節省find多次的時間。
步驟一 List的使用
數據源可以有多種形式,比如是一個數組,或者是一個list 其作用是使lisview中每一行顯示出數據源的每一個元素的值。
比如ListView中每一個item只有一個控制項 TextView 則list可以定義成一個字元串數組,或者一個ArrayList
如果ListView中每一個item有很多個控制項,則可以把多個控制項的值類型定義成一個類如Item類 格式如下
public class Item{
String name;
String text;
int number;
int imageId;
//省略setter和getter方法
}
則此時List定義成List
List<Item> listItems = new ArrayList<>();
並賦予值如下
for(int i = 0 ; i < 10 ; i ++){
Item item = new Item();
item.setName("sqf");
item.setText("Hello World");
item.setNumber(i);
item.setImageId( R.drawable.ic_launcher);
listItems.add(item);
}
或者將多個控制項的值的類型包裝成Map ,改成如下格式:
List<Map<String , Object>> listItems = new ArrayList<Map<String , Object>>();
Map<String, Object> map;
for(int i=0;i<10;i++)
{
map = new HashMap<String, Object>();
map.put("imageId", R.drawable.ic_launcher);
map.put("text", "hello World");
map.put("name" , "sqf");
map.put("number", i);
listItems.add(map);
}
此時list已經構建完畢,已經得到了需要加入ListView中的值了。
步驟二 編寫需要ListView佈局文件以及ListView中item的佈局文件
ListView佈局文件的例子如下:
activity所在的佈局XML中只需要含有listview的控制項,listview中每一行的item的具體佈局則在另一個xml文件中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView android:id="@+id/list_view"
android:layout_height="match_parent"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
ListView的Item的佈局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:gravity="center_horizontal"
android:textSize="20dp"/>
</LinearLayout>
步驟三 創建一個繼承自BaseAdapter的類
例子如下所示:
private class ExampleAdapter extends BaseAdapter{
private LayoutInflater mInflater = null;
private ExampleAdapter(Context context){
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return listItems.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
這裡主要需要重寫的方法有getcount 和getView 因為在繪製listview的時候需要多次調用getcount方法和getView方法。這裡getCount的返回值就是第一步裡面定義的listItems大小。同時在這個類里定一個成員變數mInflater和一個構造方法。
layoutInflater的作用
LayoutInflater的作用類似於findviewById() .不同在於LayoutInflater是用來找res/layout下的xml佈局文件,並且實例化。
具體作用如下:1 對於一個沒有載入或者想要動態載入的界面,都需要使用Layoutinflater.inflater() 來載入。
2 對於已經載入的界面,就可以使用Activity.findViewById()方法來獲取其中的界面元素。
獲得layoutInflater實例的三種方式
1 layoutinflater inflater = getLayoutInflater();
2 LayoutInflater localinflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
3 LayoutInflater inflater = LayoutInflater.from(context)
這三種的本質都是調用context.getSystemService()
獲得實例之後可以通過實例調用該類的方法inflate 這個方法有一下幾種的過載形式,返回值均為View對象.
public View inflate (int resource, ViewGroup root)
public View inflate (XmlPullParser parser, ViewGroup root)
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
示例代碼如下:
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
//下麵第二個參數可以為Null
View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));
//EditText editText = (EditText)findViewById(R.id.content);// error
EditText editText = (EditText)view.findViewById(R.id.content);
步驟四 為ListView 綁定適配器
首先實例化自定義的Adapter,然後找到listview視圖的對象,用setAdapter方法為ListVIew綁定適配器。
例子如下:
private ListView listview;
private ExampleAdapter adapter = new ExampleAdapter();
listview.setAdapter(adapter);
步驟五 六 覆蓋getView方法
View getView():返回列表項對應的視圖,方法體中
1 ◆實例化視圖填充器
2 ◆用視圖填充器,根據Xml文件,實例化視圖
3 ◆根據佈局找到控制項,並設置屬性
4 ◆返回View視圖
實例如下:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
if(convertView == null){
convertView = mInflater.inflate(R.layout.item_list_view,null);
viewHolder.textView = (TextView)convertView.findViewById(R.id.list_view_text);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.textView.setText(listItems.get(position));
return convertView;
}
private class ViewHolder{
TextView textView;
}
這裡調用自帶的convertview ,如果緩存為空 將LayoutInflater的實例賦給convertview,convertview用來存儲載入佈局(listview的item 的layout)的layout.xml,同時在講載入佈局內的findViewById的值放到viewHoler中。如果convertview不為空,則將findviewById的值取出來。這裡就完成了實例化視圖以及根據佈局查找控制項。接下里將存儲數據的listItems來給view中的控制項設置屬性。最後返回view視圖。