起源:ListView是Android开发中使用最广泛的一种控件,它以垂直列表的形式显示所有列表项。
创建ListView有两种方式:
☆ 直接使用ListView进行创建。
☆让Activity继承ListActivity。
一旦在程序中获得了ListView之后,接下来就需要为ListView设置它要显示的列表子项,借助Adapter来实现。
ListView常用XML属性
下面通过一个简单的例子来展示ListView的基本使用方法,效果图见文章结尾。
一、XML Code
1.activiyt_main.xml
在主xml文件内只添加一个ListView控件。
代码如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="horizontal"> 5 6 <ListView 7 android:id="@+id/list_view" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" > 10 </ListView> 11 12 </LinearLayout>
2.item.xml
在这个xml内设置每个子列的布局样式,此处简单添加一个ImageView和TextView,分别用来显示汽车Logo和品牌。
代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="horizontal" 6 android:padding="5dp" 7 android:background="#FFFFFF"> 8 9 <ImageView 10 android:id="@+id/car_logo" 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content"/> 13 <TextView 14 android:id="@+id/car_name" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:layout_gravity="center" 18 android:layout_marginLeft="10dp"/> 19 20 </LinearLayout>
二、Java Code
首先从网上下了一组汽车Logo作为素材。
接着定义一个实体类,作为ListView适配器的适配类型。
1.Car.java
Car类只有两个属性:品牌名字和LogoId,以及getName()和getLogoId两个方法。
代码如下:
1 package com.michael.listviewtest; 2 3 public class Car { 4 5 private String name; 6 7 private int logoId; 8 9 public Car(String name, int logoId) { 10 this.name = name; 11 this.logoId = logoId; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public int getLogoId() { 19 return logoId; 20 } 21 22 }
前文已经讲过,若想展现ListView内的子项,需要创建一个自定义的适配器。此处将自定义的适配器继承自ArrayAdapter,并将泛型指定为Car类。
2.CarAdapter.java
重点重写getView()方法,这个方法在每个子项被滚动到屏幕内时都会被调用。首先通过getItem()方法得到当前子项的Car实例。为了提高性能,对ListVie进行适当优化。在CarAdapter类增加一个内部类ViewHolder,用于对控件的实例进行缓存。当convertView为空的时候,首先使用LayoutInflater的inflater()方法为子项加载传入的布局,再创建一个ViewHolder对象,并将控件的实例都存放在ViewHolder里,然后调用ViewHolder的setTag()方法,将ViewHolder对象存储在View中。当convertView不为空时则调用View的getTag()方法,把ViewHolder重新取出。这样的话,所有的控件实例都缓存在ViewHolder里,省去了每次通过findVoewById()方法来获取控件实例的步骤,提高了ListView的运行效率。
代码如下:
1 package com.michael.listviewtest; 2 3 import java.util.List; 4 5 import android.content.Context; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.ArrayAdapter; 10 import android.widget.ImageView; 11 import android.widget.TextView; 12 13 public class CarAdapter extends ArrayAdapter<Car>{ 14 15 private int resourceId; 16 17 public CarAdapter(Context context, int resource, List<Car> objects) { 18 super(context, resource, objects); 19 resourceId = resource; 20 } 21 22 @Override 23 public View getView(int position, View convertView, ViewGroup parent) { 24 Car car = getItem(position); 25 View view; 26 ViewHolder viewHolder; 27 if(convertView == null) { 28 view = LayoutInflater.from(getContext()).inflate(resourceId, null); 29 viewHolder = new ViewHolder(); 30 viewHolder.carLogo = (ImageView)view.findViewById(R.id.car_logo); 31 viewHolder.carName = (TextView)view.findViewById(R.id.car_name); 32 view.setTag(viewHolder); 33 }else { 34 view = convertView; 35 viewHolder = (ViewHolder)view.getTag(); 36 } 37 viewHolder.carLogo.setImageResource(car.getLogoId()); 38 viewHolder.carName.setText(car.getName()); 39 return view; 40 } 41 42 class ViewHolder { 43 ImageView carLogo; 44 TextView carName; 45 } 46 }
3.MainActivity.java
最后把视图的加载,数据的初始化以及ListView和Adapter的适配操作添加到MainActivity里。
此外为ListView的每个子项添加一个点击事件,通过setOnItemClickListener()方法,并重写onItemClick()方法,此处就通过Toast子项包含实例的名字简单实现。
代码如下:
1 package com.michael.listviewtest; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.AdapterView; 10 import android.widget.AdapterView.OnItemClickListener; 11 import android.widget.ListView; 12 import android.widget.Toast; 13 14 public class MainActivity extends Activity { 15 16 private List<Car> carLists = new ArrayList<Car>(); 17 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 initCars(); 23 CarAdapter adapter = new CarAdapter(MainActivity.this, R.layout.item, carLists); 24 ListView listView = (ListView)findViewById(R.id.list_view); 25 listView.setAdapter(adapter); 26 listView.setOnItemClickListener(new OnItemClickListener() { 27 28 @Override 29 public void onItemClick(AdapterView<?> parent, View view, int position, 30 long id) { 31 Car car = carLists.get(position); 32 Toast.makeText(MainActivity.this, car.getName(), Toast.LENGTH_SHORT).show(); 33 } 34 }); 35 } 36 37 public void initCars() { 38 Car lotus = new Car("Lotus", R.drawable.lotus); 39 carLists.add(lotus); 40 Car lamboghini = new Car("Lamboghini", R.drawable.lamboghini); 41 carLists.add(lamboghini); 42 Car bmw = new Car("BMW", R.drawable.bmw); 43 carLists.add(bmw); 44 Car fiat = new Car("Fiat", R.drawable.fiat); 45 carLists.add(fiat); 46 Car cadillac = new Car("Cadillac", R.drawable.cadillac); 47 carLists.add(cadillac); 48 Car mercedes = new Car("Mercedes", R.drawable.mercedes); 49 carLists.add(mercedes); 50 Car skoda = new Car("Skoda", R.drawable.skoda); 51 carLists.add(skoda); 52 Car volvo = new Car("Volvo", R.drawable.volvo); 53 carLists.add(volvo); 54 Car nissan = new Car("Nissan", R.drawable.nissan); 55 carLists.add(nissan); 56 Car ferrari = new Car("Ferrari", R.drawable.ferrari); 57 carLists.add(ferrari); 58 Car porsche = new Car("Porsche", R.drawable.porsche); 59 carLists.add(porsche); 60 Car rollsroyce = new Car("Rollsroyce", R.drawable.rollsroyce); 61 carLists.add(rollsroyce); 62 } 63 }
效果图如下: