ListView主要是用來解決大量資料展示的問題,它的用途很廣泛,幾乎所有的app都會用到,比如說知乎、今日頭條、微網誌、通訊錄等。
ListView允許使用者通過上下滑動的方式将螢幕外的資料滾動到螢幕中,同時原來的資料會滾動出螢幕。
1.ArrayAdapter的用法
①在布局中編寫代碼(添加ListView标簽)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
複制
加入ListView标簽的方法很簡單,隻需要聲明id,設定width和height即可。這時候會出現一個預覽的界面:
可以看出整個界面全部被listview占據。
②修改MainActivity中的代碼
需要完成的步驟可以分解為:
1.擷取ListView對象
2.準備資料源
3.配置擴充卡
4.将擴充卡關聯到ListView上
package es.source.code.activity.simplelistviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
//準備資料源
private String[] data = {"apple", "banana", "orange", "watermelon", "pear", "grape", "pineapple", "strawberry", "cherry", "mango"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//配置擴充卡
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);
//擷取ListView對象
ListView listView = (ListView)findViewById(R.id.list_item1);
//将擴充卡關聯到ListView
listView.setAdapter(adapter);
}
}
複制
ListView顯示的資料一般都是從資料庫中拿到的資料,在這裡使用的是一個簡單的數組來模拟這些資料。
檢視源碼可以發現這一部分的要求是
public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull T[] objects) {
this(context, resource, 0, Arrays.asList(objects));
}
複制
ArrayAdapter适用于簡單的文字清單的适配,同時它的參數清單包含上下文、ListView子項布局的id以及要适配的資料。
在這裡我們是用的是系統自帶的android.R.layout.simple_list_item_1,裡面隻有一個TextView,可以用于簡單的顯示一段文本。
最後調用ListView的setAdapter()方法,将建構好的擴充卡對象傳遞進去。這樣就使得ListView和資料之間的關聯建立起來了。
定制ListView的界面
①建立一個Fruit類
public class Fruit
{
private String name;
private int imageId;
public Fruit(String name, int imageId)
{
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
複制
這個類的作用是作為ListView擴充卡的适配類型。其中name表示水果的名字,imageId表示水果對應的圖檔資源。
②為ListView的子項指定一個自定義的布局
建立一個fruit_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">
<ImageView
android:id="@+id/fruit_image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
複制
在這裡定義了一個ImageView用于顯示水果的圖檔,定義了一個TextView用于顯示水果的名稱。
③建立一個自定義的擴充卡
這個擴充卡繼承自ArrayAdapter,并将泛型指定為Fruit類。
public class FruitAdapter extends ArrayAdapter
{
private int resourceId;
public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects)
{
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}
public View getView(int position, View convertView, ViewGroup parent)
{
Fruit fruit = (Fruit) getItem(position);
View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
ImageView fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView)view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
}
複制
首先要重寫父類的構造函數,用于将上下文、ListView子項布局的id和資料都傳遞進去。此外重寫了getView()方法,這個方法在每個子項滾動到螢幕内的時候被調用。在getView()方法中,首先通過getItem()方法得到目前項的Fruit執行個體,然後通過LayoutInflater來為這個子項加載我們傳入的布局,接着調用View的findViewById()方法分别擷取ImageView和TextView執行個體,并分别調用它們的setImageResource()和setText()方法來設定顯示的圖檔和文字,最後将布局傳回。
④修改MainActivity,關聯ListView
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<Fruit>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);
ListView listView = (ListView)findViewById(R.id.fruit_item);
}
private void initFruits()
{
複制
Fruit apple = new Fruit("Apple", R.drawable.ic_account_circle_black_48dp);
fruitList.add(apple);
Fruit apple1 = new Fruit("Apple", R.drawable.ic_add_shopping_cart_black_48dp);
fruitList.add(apple1);
Fruit apple2 = new Fruit("Apple", R.drawable.ic_alarm_add_black_48dp);
fruitList.add(apple2);
Fruit apple3 = new Fruit("Apple", R.drawable.ic_aspect_ratio_black_48dp);
fruitList.add(apple3);
Fruit apple11 = new Fruit("Apple", R.drawable.ic_account_circle_black_48dp);
fruitList.add(apple11);
Fruit apple111 = new Fruit("Apple", R.drawable.ic_add_shopping_cart_black_48dp);
fruitList.add(apple111);
Fruit apple211 = new Fruit("Apple", R.drawable.ic_alarm_add_black_48dp);
fruitList.add(apple211);
Fruit apple311 = new Fruit("Apple", R.drawable.ic_aspect_ratio_black_48dp);
fruitList.add(apple311);
Fruit apple22 = new Fruit("Apple", R.drawable.ic_account_circle_black_48dp);
fruitList.add(apple22);
Fruit apple12 = new Fruit("Apple", R.drawable.ic_add_shopping_cart_black_48dp);
fruitList.add(apple12);
Fruit apple222 = new Fruit("Apple", R.drawable.ic_alarm_add_black_48dp);
fruitList.add(apple222);
Fruit apple32 = new Fruit("Apple", R.drawable.ic_aspect_ratio_black_48dp);
fruitList.add(apple32);
複制
} }
複制
2.SimpleAdapter的用法
一、在布局檔案中寫代碼
1.在activity_main.xml中添加ListView标簽
2.在item.xml中編寫行布局檔案
二、在activity中編寫代碼
1.擷取ListView對象
2.準備資料源
3.配置擴充卡
4.将擴充卡關聯到ListView上
①設定activity_main.xml
聲明ListView控件(注意必須使用LinearLayout)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/mylist"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
複制
②設定simple_item.xml
設定具體的ListView的一行中的控件的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp" />
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:paddingLeft="10dp"/>
<TextView
android:id="@+id/desc"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="10dp"
android:paddingLeft="10dp"/>
</LinearLayout>>
</LinearLayout>
複制
③MainActivity.java
public class MainActivity extends Activity
{
private String[] names = new String[]{"膜法師1号","膜法師2号","膜法師3号","膜法師4号",
"膜法師5号","膜法師6号","膜法師7号","膜法師8号",
"膜法師9号","膜法師10号","膜法師11号","膜法師12号"};
private String[] descs = {"我為長者續一秒","最喜歡談笑風生","這時候我想吟兩句詩","總想搞個大新聞","我為長者續1秒",
"别總想搞大新聞","比你們不知道高到哪裡去","西方哪個國家我沒去過","水可載舟亦可覆舟","too young, too simple",
"你們啊,naive","蛤蛤蛤"};
private int[] imageIds = new int[]{
R.drawable.pic1, R.drawable.pic2,R.drawable.pic3, R.drawable.pic4,
R.drawable.pic5, R.drawable.pic6,R.drawable.pic7, R.drawable.pic8,
R.drawable.pic9, R.drawable.pic10,R.drawable.pic11, R.drawable.pic12};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//建立一個List集合,List集合的元素是map
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
for(int i = 0; i < names.length; i++)
{
Map<String, Object> listItem = new HashMap<>();
listItem.put("header", imageIds[i]);
listItem.put("personName", names[i]);
listItem.put("desc", descs[i]);
listItems.add(listItem);
}
//建立一個SimpleAdapter
SimpleAdapter simpleAdapter = new SimpleAdapter(
this,
listItems,//
R.layout.simple_item,//listview的布局情況
new String[]{"personName", "header", "desc"},
new int[]{R.id.name, R.id.header, R.id.desc}
);
ListView list = (ListView)findViewById(R.id.mylist);
//為ListView設定Adapter
list.setAdapter(simpleAdapter);
}
}
複制
注意SimpleAdapter的參數清單
第一個參數:聲明上下文
第二個參數:該參數應該是一個List<? extends Map<String, ?>>類型的資料集合對象,每個對象生成一個具體的清單項;
第三個參數:制定了一個界面布局的ID,在這裡使用的是simple_item.xml作為清單項元件;
第四個參數:該參數應該是一個String[]類型的參數,該參數決定提取Map<String, ?>對象中哪些key對應的value來生成
3.自定義Adapter
由于ArrayAdapter和SimpleAdapter不能滿足所有的需求,是以我們可能需要自己定義Adapter來實作某些功能。
具體的步驟如下:
1.建立自己的adapter,繼承自BaseAdapter,重寫以下四個方法:
(1)public int getCount();
(2)public Object getItem(int position);
(3)public long getItemId(int position);
(4)public View getView(int position, View convertView, ViewGroup parent)。
2.添加資料集合和反射器實作構造器和setter方法;
4.實作getView方法;
5.關聯ListView。