ListView可以说是我们在进行Android开发时候最常见的控件之一了,那么我们该如何使用呢?这里主要介绍两种方法。
- 使用Activity(继承自AppCompactActivity)+ListView控件
- 使用Activity(继承自ListActivity)
继承自AppCompactActivity
首先,让我们来看看第一种方法。用一个小例子来介绍一下。
Step1:新建一个工程,修改activity_main.xml的代码如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.xkw.listviewtest.MainActivity">
<ListView
android:id="@+id/listview_fruit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
在这里我们只添加了一个ListView的控件,并没有添加其它的东西。
Step2:如图,layout右键->new->Layout Source File,新建一个listitem.xml文件。这个listitem就是listview里面的每一个小单元要显示的东西,这里我们只显示一个字符串就只添加一个TextView控件就行。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/fruit_name"
android:layout_width="match_parent"
android:layout_height="51dp"
android:textSize="24sp" />
</android.support.constraint.ConstraintLayout>
Step3:在MainActivity里面修改代码如下
package com.example.xkw.listviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
//自己定义的一组用于显示的数据
private String[] fruit =
{"苹果","香蕉","橙子","西瓜","梨","葡萄","菠萝","草莓","芒果","蔓越莓",
"榴莲","山竹","柚子","哈密瓜","水蜜桃","番石榴","黄桃","蛇果","蜜瓜","蓝莓","甘蔗"};
private FruitAdapter mfruitAdapter;
private ListView mlistView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mlistView = (ListView)findViewById(R.id.listview_fruit);
mfruitAdapter = new FruitAdapter();
initFruits();
mlistView.setAdapter(mfruitAdapter);
mlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this,"您选择了:" + ((Fruit) mfruitAdapter.getItem(i)).getName(),Toast.LENGTH_SHORT).show();
}
});
}
private void initFruits(){
for (int i = 0;i < fruit.length;i ++){
Fruit newfruit = new Fruit(fruit[i]);
mfruitAdapter.addFruit(newfruit);
}
}
public class Fruit{
//定义了一个水果类
private String Name;
//private int ImageId; //用于存放水果图片的Id,此处没有
public Fruit(String name){
this.Name = name;
}
public String getName(){
return Name;
}
}
private class FruitAdapter extends BaseAdapter{
private ArrayList<Fruit> mFruit;
private LayoutInflater mInflator;
public FruitAdapter(){
super();
mFruit = new ArrayList<Fruit>();
mInflator = MainActivity.this.getLayoutInflater();
}
public void addFruit(Fruit fruit){
mFruit.add(fruit);
}
@Override
public int getCount() {
return mFruit.size();
}
@Override
public Object getItem(int i) {
return mFruit.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
//常规ListView优化代码
if (view == null){
//注意inflate()的第三个参数必须设置为false,不然会和onCreate函数里面的setContentView冲突
view = mInflator.inflate(R.layout.listitem,null,false);
viewHolder = new ViewHolder();
viewHolder.fruitName = (TextView)view.findViewById(R.id.fruit_name);
view.setTag(viewHolder);//将ViewHolder储存至view内
}
else {
viewHolder = (ViewHolder)view.getTag();//从view内读取ViewHolder
}
Fruit fruit = mFruit.get(i);
viewHolder.fruitName.setText(fruit.getName());
return view;
}
class ViewHolder{
//定义了一个内部类ViewHolder用于对每一个水果的信息进行缓存
TextView fruitName;
}
}
}
下面我们来详细分析一下这段代码。
首先先解释一下定义的几个类:
- Fruit类是一个水果类,用于存放每一个水果的相关信息(名字,价钱,图片……这里为了简便只有一个名字);
- FruitAdapter类继承于BaseAdapter,是一个自己定义的Adapter;
- ViewHolder是一个内部类,用于缓存读取到的Fruit类实例的Name变量(这样就不用每一次都用findviewbyid()去找这个变量)。
首先,自己预先定义一些用于显示的数据。
private String[] fruit =
{"苹果","香蕉","橙子","西瓜","梨","葡萄","菠萝","草莓","芒果","蔓越莓",
"榴莲","山竹","柚子","哈密瓜","水蜜桃","番石榴","黄桃","蛇果","蜜瓜","蓝莓","甘蔗"};
然后,在onCreate()函数里面绑定ListView控件并设定相应的Adapter即可(Adapter是数据(Data)和界面(UI)之间的桥梁)。总的来说,只需要一下这么几步:绑定控件->添加数据->设定Adapter,就可以实现ListView的显示功能了。
setContentView(R.layout.activity_main);//加载布局文件
mlistView = (ListView)findViewById(R.id.listview_fruit);//绑定控件
mfruitAdapter = new FruitAdapter();//新建一个Adapter
initFruits();//添加数据
mlistView.setAdapter(mfruitAdapter);//设定Adapter
这么几行代码就已经可以完成显示的功能了,话不多说,直接来看看实际效果图。
但是假如一个ListView只有显示的功能未免太过鸡肋,那么就让我们来添加一下点击处理函数。其实很简单,只需要直接调用listview的setOnItemClickListener()函数即可(参数i就是点击的单元的序号)。如下,我们在里面通过Toast显示用户点击了哪一个水果。
mlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this,"您选择了:" + ((Fruit) mfruitAdapter.getItem(i)).getName(),Toast.LENGTH_SHORT).show();
}
});
至此为止,一个完整的ListView就已经实现了。以上就是介绍的第一种实现ListView的方法。
继承自ListActivity
下面介绍第二种实现ListView的方法,就是让这个类继承自ListActivity。
public class MainActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
}
}
然后其他的就和第一种用法差不多了,同样的新建Fruit和FruitAdapter,ViewHolder三个类。需要注意的是,ListActivity是没有布局文件的!!!但是Android Studio默认生成的是继承自AppCompactActivity的活动,在onCreate()函数里面会加载布局文件,所以假如创建的时候没有注意勾选不要布局文件的话一定要注意把onCreate()函数里面的setContentView(R.layout.activity_main);这句话注释掉!!!不然运行会报错。
介绍一下使用ListActivity相较于第一种方法的几个细微之处。
- ListActivity本身已经定义了点击函数,我们需要做的只是重载一下就好了。
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(MainActivity.this,"您选择了:" + ((Fruit) mfruitAdapter.getItem(position)).getName(),Toast.LENGTH_SHORT).show();
}
- 同样绑定Adapter的函数ListActivity也已经帮我们做好了,我们只需要直接调用就好了。
setListAdapter(mfruitAdapter);
程序运行之后,可以看到与第一种效果一模一样,具体图在这里就不贴了。
ListView的两种实现方法就介绍到这里了。理论上来说用哪种方法都是可以的,看你喜欢用哪种而已。但是个人比较推荐第一种方法,使用listview控件,不要继承于ListActivity。因为继承自ListActivity的话是没有布局文件的,能修改的只有默认的ActionBar,但是Google现在已经推出了Material Design,而ActionBar也被更灵活的ToolBar所取代,越来越多的应用也开始采用ToolBar的设计方式,但是使用ToolBar需要自己定义布局文件,与ListActivity不能使用布局文件是矛盾的,所以更建议大家使用listview控件。以上纯属个人之愚见,欢迎有不同意见的评论交流。