ListView是Android中的一个控件,它可以通过滑动的方式在界面上显示大量的数据,并且不会占用大量内存。比如有一个数据源是100种水果名,通过使用ListView控件可以将这100种水果名显示到手机屏幕上。由于屏幕的大小限制,可能每次只能创造10个子视图显示10种水果名,那么剩下的水果名就可以通过滑动屏幕的方式加载到内存中显示在屏幕上,而不需要同时创造100个子视图加载100个水果名,通过这样的方式,就算要显示更多的数据,占用的内存也不会增加。
但是ListView不能直接将数据源显示到屏幕上,它们之间进行交互需要一个桥梁:Adapter(适配器)。这是因为数据源种类繁杂,如果将匹配数据的工作交给ListView控件就会显得非常臃肿,也不符合Android风格,因此将操作数据的工作交给Adapter,ListView只需要关心Adapter部分。
使用ListView控件需要完成3个内容:1.子视图布局。2.待显示的数据源。3.Adapter(适配器)。
1.子视图布局
ListView控件是用来显示数据的,数据在ListView中是一条一条垂直排列的显示,每一条都是一个子视图。比如要显示水果名,子视图布局内就只有一个TextView控件,如果要在水果名旁边显示一个水果图片,子视图布局内就有一个TextView控件和一个ImageView控件。所以需要根据待显示数据的种类自定义相应的子视图布局。布局代码很简单,这里假定已经自定义了一个显示水果名和图片的子视图布局fruit_item.xml。
2.待显示的数据源
根据上面的布局文件,需要显示水果名和对应的水果图片,可以定义一个Fruit类,类成员变量有name和imageId两个,name表示水果名,imageId表示水果图片的资源id。类成员方法有getName()和getImageId()两个,分别获取水果名字和水果图片。
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 String getimageId(){
returnimageId;
}
}
3.Adapter(适配器)
一般需要根据待显示的数据自定义对应的Adapter,我们这里将水果图片和名字显示在屏幕上,所以需要定义一个FruitAdapter,并将数据泛型指定为Fruit类。代码如下:
public class FruitAdapter extends ArrayAdapter{
private int resourceId;
public FruitAdapter(Context context,int textViewResourceId,Listobjects){
super(context,textViewResourceId,objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position,View convertView,ViewGroup parent){
//根据position获取待显示的Fruit实例
Fruit fruit = getItem(position);
//获取子视图控件实例
View view = LayouInflater.from(getContext()).inflate(resourceId,parent,false);
ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
//将Fruit实例内的水果名和水果图片赋值给子视图控件实例
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
FruitAdapter类中有一个构造函数和一个getView()方法,构造函数中将上下文、子视图布局id、数据传递进来。而当上下滑动屏幕将待显示的数据显示到屏幕上时就会调用getView()方法。
比如屏幕上只能够显示前10个水果数据,当往上滑动屏幕时就会加载第11个水果数据,具体的加载过程就是在getView()方法中完成的。方法具体步骤如下:
(1)首先通过position参数获取第11个水果数据的实例。
(2)然后使用LayoutInflater将子视图布局文件动态加载到子视图view中。
(3)使用view.findViewById()方法获取子视图view内的两个控件实例。
(4)将第1步的水果数据写入到第3步中的控件实例当中 。
(5)最后返回子视图view。
上述3个部分的内容都完成之后就可以在活动中使用ListView了,代码如下:
public class MainActivity extends AppCompatActivity{
private List fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();//初始化水果数据
FruitAdapter adapter = newFruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
ListView listview = (ListView) findViewById(R.id.list_view);
ListView.setAdapter(adapter);
}
private void initFruits(){
for(int i = 0;i<2;i++){
Fruit apple = new Fruit("Apple",R.drawable.apple_pic);
fruitList.add(apple);
.
.
.
}
}
}
首先创建了一个水果类列表fruitList,通过initFruits()方法将水果数据输入到fruitList当中。然后创建FruitAdapter对象,参数有上下文MainActivity.this、子视图布局文件fruit_item、数据源fruitList。最后将FruitAdapter对象传递给ListView实例的setAdapter()方法。