• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

ListView的使用(Android学习笔记之第七课)

互联网 diligentman 5天前 4次浏览

ListView的使用

文章目录

  • ListView的使用
  • 前言
  • 一、ListView常用的属性
  • 二、ListView的简单用法
  • 三、定制ListView的界面
  • 四、提升ListView的运行效率
  • 五、LIstView的点击事件

前言

ListView是Android开发中最常用的组件,基本上每一个安卓应用都会使用ListView。在使用ListView的时候一定会使用到Adapter(适配器)。
ListView中常用的适配器有三种,分别是:BaseAdapter、SimpleAdapter、ArrayAdapter。这里的适配器其实就是相当于把数据映射到ListView上的中介。


一、ListView常用的属性

属性名称 属性功能
android:cacheColorHint 设置拖动的背景色
android:divider 设置分割线
android:dividerHeight 设置分割线的高度
android:listSelector 设置ListView item选中时的颜色
android:scrollbars 设置Listview的滚动条
android:fadeScrollbars 设置为true就可以实现滚动条的自动隐藏和显示

二、ListView的简单用法

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="wrap_content"/>

</LinearLayout>

MainActivity的代码如下:

public class MainActivity extends AppCompatActivity {
    private String[] data={"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango","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)findViewById(R.id.list_view);
        listView.setAdapter(adapter);
      }
    }

Android 中提供了很多适配器的实现类,其中我认为最好用的就是 ArrayAdapter。它可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据类型传入即可。ArrayAdapter 有多个构造函数的重载,你应该根据实际情况选择最合适的一种。这里由于我们提供的数据都是字符串,因此将 ArrayAdapter 的泛型指定为 String,然后在 ArrayAdapter 的构造函数中依次传入当前上下文、ListView 子项布局的 id,以及要适配的数据。注意我们使用了 android.R.layout.simple_list_item_1 作为 ListView 子项布局的 id,这是一个 Android 内置的布局文件,里面只有一个 TextView,可用于简单显示一段文本。这样适配器对象就构建好了。
最后,还需要调用 ListView 的 setAdapter() 方法,将构建好的适配器对象传递进去,这样 ListView 和数据之间的关联就建立完成了。

运行效果
ListView的使用(Android学习笔记之第七课)


三、定制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;
	}
 
}

Fruit 类中只有两个字段,name 表示水果的名字,imageId 表示水果对应图片的资源 id。
然后需要为 ListView 的子项指定一个我们自定义的布局,在 layout 目录下新建 fruit_item.xml,代码如下所示:

<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="wrap_content"
        android:layout_height="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="10dip" />
 
</LinearLayout>

在这个布局中,我们定义了一个 ImageView 用于显示水果的图片,又定义了一个 TextView 用于显示水果的名称。
接下来需要创建一个自定义的适配器,这个适配器继承自 ArrayAdapter,并将泛型指定为 Fruit 类。新建类 FruitAdapter,代码如下所示:

public class FruitAdapter extends ArrayAdapter<Fruit> {
 
	private int resourceId;
 
	public FruitAdapter(Context context, int textViewResourceId,
			List<Fruit> objects) {
		super(context, textViewResourceId, objects);
		resourceId = textViewResourceId;
	}
 
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		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;
	}
}

FruitAdapter 重写了父类的一组构造函数,用于将上下文、ListView 子项布局的 id 和数据都传递进来。另外又重写了 getView() 方法,这个方法在每个子项被滚动到屏幕内的时候会被调用。在 getView() 方法中,首先通过 getItem() 方法得到当前项的 Fruit 实例,然后使用 LayoutInflater 来为这个子项加载我们传入的布局,接着调用 View 的 findViewById() 方法分别获取到 ImageView 和 TextView 的实例,并分别调用它们的 setImageResource() 和 setText() 方法来设置显示的图片和文字,最后将布局返回,这样我们自定义的适配器就完成了。

下面修改 MainActivity 中的代码,如下所示:

public class MainActivity extends Activity {
 
	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.list_view);
		listView.setAdapter(adapter);
	}
	
	private void initFruits() {
		Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
		fruitList.add(apple);
		Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
		fruitList.add(banana);
		Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
		fruitList.add(orange);
		Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
		fruitList.add(watermelon);
		Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
		fruitList.add(pear);
		Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
		fruitList.add(grape);
		Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
		fruitList.add(pineapple);
		Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
		fruitList.add(strawberry);
		Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
		fruitList.add(cherry);
		Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
		fruitList.add(mango);
	}
 
}

可以看到,这里添加了一个 initFruits() 方法,用于初始化所有的水果数据。在 Fruit 类的构造函数中将水果的名字和对应的图片 id 传入,然后把创建好的对象添加到水果列表中。接着我们在 onCreate() 方法中创建了 FruitAdapter 对象,并将 FruitAdapter 作为适配器传递给了 ListView。这样定制 ListView 界面的任务就完成了。

运行效果
ListView的使用(Android学习笔记之第七课)

四、提升ListView的运行效率

修改FruitAdapter中的代码,如下所示:

public class FruitAdapter extends ArrayAdapter<Fruit> {
        ......
 
       @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Fruit fruit = getItem(position);
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);
            viewHolder = new ViewHolder();
            viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
            view.setTag(viewHolder);
        } else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }
        viewHolder.fruitImage.setImageResource(fruit.getImageId());
        viewHolder.fruitName.setText(fruit.getName());
        return view;
    }
    
    class ViewHolder {
        
        ImageView fruitImage;
        
        TextView fruitName;
        
    }
}

仔细观察,getView() 方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。我们新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView 为空的时候,创建一个 ViewHolder 对象,并将控件的实例都存放在 ViewHolder 里,然后调用 View 的 setTag() 方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用 View 的 getTag() 方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder 里,就没有必要每次都通过 findViewById() 方法来获取控件实例了。

五、LIstView的点击事件

修改MainActivity中的代码,如下所示:

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.list_view);
        listView.setAdapter(adapter);
        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();
            }
        });


    }

...

}

可以看到,我们使用了 setOnItemClickListener() 方法来为 ListView 注册了一个监听器,当用户点击了 ListView 中的任何一个子项时就会回调 onItemClick() 方法,在这个方法中可以通过 position 参数判断出是哪一个子项,然后获取到相应的水果,并通过 Toast 将水果的名字显示出来。

运行效果
ListView的使用(Android学习笔记之第七课)


程序员灯塔
转载请注明原文链接:ListView的使用(Android学习笔记之第七课)
喜欢 (0)