ListView是Android中最常用的控制元件之一,幾乎所有的應用程式都會用到它,因此學會運用它很重要,下面我們從一個例子中去理解ListView的用法,先看一下我們這個例子的專案結構圖

這里我們先看Fruit,FruitAdapter 和fruit_item這三個檔案
Fruit是作為ListView配接器的型別
FruitAdapter是繼承ArrayAdapter的配接器
fruit_item是ListView的子項布局檔案
那么問題就來了,為什么要有配接器?它的作用又是什么呢?
之所以要有配接器是因為我們的資料不能直接傳遞給ListView,因此我們需要借助配接器來完成資料的傳遞,而ArrayAdapter是android中比較好用的一種,可以通過泛型來指定要適配的資料型別,然后在建構式中把要適配的資料傳入
下面我們就來看一下各個部分的代碼,首先我們來看一下MainActivity的代碼
package com.example.apple.listviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
// fruitList用于存盤資料
private List<Fruit> fruitList=new ArrayList<>();
@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.list_view);
listView.setAdapter(adapter);
// 為ListView注冊一個監聽器,當用戶點擊了ListView中的任何一個子項時,就會回呼onItemClick()方法
// 在這個方法中可以通過position引數判斷出用戶點擊的是那一個子項
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fruit fruit=fruitList.get(position);
Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
}
// 初始化資料
private void initFruits(){
for(int i=0;i<10;i++){
Fruit a=new Fruit("a",R.drawable.a);
fruitList.add(a);
Fruit b=new Fruit("B",R.drawable.b);
fruitList.add(b);
Fruit c=new Fruit("C",R.drawable.c);
fruitList.add(c);
Fruit d=new Fruit("D",R.drawable.d);
fruitList.add(d);
}
}
}
代碼也不復雜,我們直接看注釋就好了
接下來看一看對應的activity_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"
>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
這里的代碼也很簡單,就是用了一個ListView控制元件
然后我們就看一下配接器FruitAdapter的代碼
package com.example.apple.listviewtest;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
// 配接器的建構式,把要適配的資料傳入這里
public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects){
super(context,textViewResourceId,objects);
resourceId=textViewResourceId;
}
// convertView 引數用于將之前加載好的布局進行快取
@Override
public View getView(int position, View convertView, ViewGroup parent){
Fruit fruit=getItem(position); //獲取當前項的Fruit實體
// 加個判斷,以免ListView每次滾動時都要重新加載布局,以提高運行效率
View view;
ViewHolder viewHolder;
if (convertView==null){
// 避免ListView每次滾動時都要重新加載布局,以提高運行效率
view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
// 避免每次呼叫getView()時都要重新獲取控制元件實體
viewHolder=new ViewHolder();
viewHolder.fruitImage=view.findViewById(R.id.fruit_image);
viewHolder.fruitName=view.findViewById(R.id.fruit_name);
// 將ViewHolder存盤在View中(即將控制元件的實體存盤在其中)
view.setTag(viewHolder);
} else{
view=convertView;
viewHolder=(ViewHolder) view.getTag();
}
// 獲取控制元件實體,并呼叫set...方法使其顯示出來
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
return view;
}
// 定義一個內部類,用于對控制元件的實體進行快取
class ViewHolder{
ImageView fruitImage;
TextView fruitName;
}
}
可以看到在FruitAdapter類中我們重寫了父類的一組建構式,用于將背景關系、ListView子項布局的id和資料都傳遞進來,另外又重寫了getView()方法,這個方法在每個子項被滾動到螢屏內的時候會被呼叫,ListView本身的運行效率是很低的,因此我們需要優化,具體的優化方法已經在代碼中了,直接看代碼注釋就知道了
現在我們再看看Fruit的代碼
package com.example.apple.listviewtest;
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;
}
}
Fruit是ListView配接器的型別,即是資料傳入到ListView中的型別,
public class FruitAdapter extends ArrayAdapter<Fruit>
看這行FruitAdapter中的代碼,我們把Fruit作為了配接器的型別
我們最后看一下fruit_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">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
代碼也不復雜,每個子項布局都顯示一張圖片和一段文字
最終效果圖如下:

總結:
使用ListView,關鍵是在配接器與配接器的型別上,這兩個方面掌握了,基本就可以定制出屬于自己的ListView界面了,ListView雖然功能強大,但是它只能實作縱向滾動的效果,如果要實作橫向滾動就有心無力了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/233498.html
標籤:Android
