ArrayAdapter
總是感覺寫自己的部落格才更能夠學到東西,網上儘管有很多好的資料,但是參差不齊,需要浪費大量時間才能夠找到最需要的,索性寫自己最需要的東西。
Adapter是適配器的意思,在Android中大量的使用到了ListView,而ListView需要與各種適配器結合才能夠使用。不同的場合使用不同的適配器,所以總結一下最常用的會對自己以後很有協助
ArrayAdapter(數組適配器)一般用於顯示一行文本資訊,所以比較容易。
public ArrayAdapter(Context context,int textViewResourceId,List<T> objects)
上面的這行代碼來裝配資料,要裝配這些資料就需要一個串連ListView視圖對象和數組資料的適配器來兩者的適配工作,ArrayAdapter的構造需要三個參數,依次為this,布局檔案(注意這裡的布局檔案描述的是列表的每一行的布局,可以參見main.xml檔案,android.R.layout.simple_list_item_1是系統定義好的布局檔案只顯示一行文字,資料來源(一個List集合)。同時用setAdapter()將ListView和Adapter綁定。
例子一:可以用來簡單的顯示一條文字
main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="cnblogs--花郎" /> <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="wrap_content" /></LinearLayout>
Activity
package com.loulijun.demo14;import java.util.ArrayList;import android.app.Activity;import android.os.Bundle;import android.widget.ArrayAdapter;import android.widget.ListView;public class Demo13Activity extends Activity { private ListView lv; private ArrayList<String> list = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView)findViewById(R.id.listview); ArrayAdapter<String> adapter = new ArrayAdapter<String>( this, android.R.layout.simple_expandable_list_item_1, getData()); lv.setAdapter(adapter); } private ArrayList<String> getData() { list.add("180平米的房子"); list.add("一個勤勞漂亮的老婆"); list.add("一輛寶馬"); list.add("一個強壯且永不生病的身體"); list.add("一個喜歡的事業"); return list; }}
注意:這裡的android.R.layout.simple_expandable_list_item_1是系統內建布局,樣式就是如下,這部分也可以自己定義布局然後倒入進去,但是只能是一個TextView
代碼很少,一看就懂。可能麻煩一些的是泛型這部分,不懂的可以翻翻JAVA的基礎。運行效果如下
例子二:這個例子可以增加一個ImageView,但是在設定ArrayAdapter的時候需要增加這個自訂的布局
public ArrayAdapter(Context context,int resource,int textViewResourceId,List<T> objects)
上面的第一個參數是上下文,一般為this。第二個參數是自訂的布局檔案,比如下面的就是R.layout.list_item。第三個參數是TextView的id,第四個參數是資料
list_item.xml(main.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="horizontal" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/tv" android:layout_width="fill_parent" android:layout_height="wrap_content" /></LinearLayout>
Activity
package com.loulijun.demo14;import java.util.ArrayList;import android.app.Activity;import android.os.Bundle;import android.widget.ArrayAdapter;import android.widget.ListView;public class Demo13Activity extends Activity { private ListView lv; private ArrayList<String> list = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView)findViewById(R.id.listview); ArrayAdapter<String> adapter = new ArrayAdapter<String>( this, R.layout.list_item, R.id.tv, getData()); lv.setAdapter(adapter); } private ArrayList<String> getData() { list.add("180平米的房子"); list.add("一個勤勞漂亮的老婆"); list.add("一輛寶馬"); list.add("一個強壯且永不生病的身體"); list.add("一個喜歡的事業"); return list; }}
這裡的ArrayAdapter與SimpleAdapter還不一樣,它需要在適配器中設定自訂的布局後還要將裡面的TextView的id設定進去。但是裡面的其他控制項比如設定不同的圖等就很麻煩實現了,一般如果需要實現
有圖片有文字的最好是用BaseAdapter或者SimpleAdaper。ArrayAdapter比較適合於簡單的現實一些文字資訊
效果如下:
例子三:實現複雜的效果
說實話,這樣寫的很蛋疼,很多效果不能實現,還是BaseAdapter更加萬能,但還是說說如何用ArrayAdapter實現複雜試圖。這就需要重寫getView方法了,類似BaseAdapter
重寫getView方法有很多好處,比如ListView最佳化的時候主要是在這個方法中的操作進行最佳化的,另外自訂的視圖基本都是通過這個方法來載入,以便達到自己理想的效果
我想顯示sd卡的/DCIM/Camera目錄中的所有圖片到一個列表中,這個列表中的每一項左邊是圖片的縮圖,右邊是檔案名稱。
分析:
這個應用是很典型的 資料繫結 加 自訂顯示.
如何搞定?
1. 自訂欄表樣式
image_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <ImageView android:id="@+id/item_thumbnail" android:layout_height="48dip" android:layout_width="48dip" /> <TextView android:id="@+id/item_file_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:minHeight="?android:attr/listPreferredItemHeight" android:gravity="center_vertical" android:paddingLeft="5dip" /></LinearLayout>
2. 自訂ArrayAdapter
ImageListAdapter
public class ImageListAdapter extends ArrayAdapter<File>{ private int resource; public ImageListAdapter(Context context, int resourceId, List<File> objects) { super(context, resourceId, objects); // 記錄下來稍後使用 resource = resourceId; } public View getView(int position, View convertView, ViewGroup parent) { LinearLayout imageListView; // 擷取資料 File file = getItem(position); String fileName = file.getName(); Bitmap bitmap = getBitmapFromFile(file); // 系統顯示列表時,首先執行個體化一個適配器(這裡將執行個體化自訂的適配器)。 // 當手動完成適配時,必須手動映射資料,這需要重寫getView()方法。 // 系統在繪製列表的每一行的時候將調用此方法。 // getView()有三個參數, // position表示將顯示的是第幾行, // covertView是從布局檔案中inflate來的布局。 // 我們用LayoutInflater的方法將定義好的image_item.xml檔案提取成View執行個體用來顯示。 // 然後將xml檔案中的各個組件執行個體化(簡單的findViewById()方法)。 // 這樣便可以將資料對應到各個組件上了。 // if(convertView == null) { imageListView = new LinearLayout(getContext()); // 看一下android文檔中關於LayoutInflater的定義吧 // This class is used to instantiate layout XML file into its corresponding View objects. // It is never be used directly -- use getLayoutInflater() or getSystemService(String) // to retrieve a standard LayoutInflater instance that is already hooked up to the current // context and correctly configured for the device you are running on. . For example: String inflater = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, imageListView, true); // 這個每次select images時都被調用 Log.d("Adapter", "convertView is null now"); } else { // 很奇怪基本沒被調用過 imageListView = (LinearLayout)convertView; Log.d("Adapter", "convertView is not null now"); } // 填充自訂資料 ImageView imageView = (ImageView) imageListView.findViewById(R.id.item_thumbnail); TextView textView = (TextView) imageListView.findViewById(R.id.item_file_name); textView.setText(fileName); imageView.setImageBitmap(bitmap); return imageListView; } // 從檔案擷取Bitmap用於填充 private Bitmap getBitmapFromFile(File file) { Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); return bitmap; } }
3. 綁定資料
private void bindFilesToList(File[] files) { List<File> fileList = new ArrayList<File>(); for(File file : files) { fileList.add(file); } ImageListAdapter adapter = new ImageListAdapter(ImageFilesListActivity.this, R.layout.image_item, fileList); setListAdapter(adapter); }
基本就是這樣了