Android最常用的控件ListView(详解)

﹏ヽ暗。殇╰゛Y 2023-09-23 16:42 246阅读 0赞

文章目录

  • 一.ListView简介
  • 二.ListView简单用法
    • 代码部分
    • 代码解析
      • 1.ArrayAdapter适配器
      • 2.点击事件响应
  • 三.定制 ListView 界面
    • 代码部分
    • 代码解析
      • 1.引入动态数组ArrayList
      • 2.Fruit类
      • 3.自定义适配器 控件 -桥梁-数据
      • 4.inflate()方法
  • 四.提升ListView的运行效率
    • 优化方法一:
    • 优化方法二:
    • 代码
  • 五.ListView的点击事件
    • 代码
  • 六.总结

一.ListView简介

在Android开发中,ListView是一个比较常用的控件。它以列表的形式 展示具体数据内容,并且能够根据数据的长度自适应屏幕显示。

二.ListView简单用法

在这里插入图片描述

代码部分

1.布局界面 activity_main.xml 代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <ListView
  9. android:id="@+id/list_view"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"/>
  12. </LinearLayout>

2.类文件 MainActivity.java 代码:

  1. package com.example.listview1;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.AdapterView;
  6. import android.widget.ArrayAdapter;
  7. import android.widget.ListView;
  8. import android.widget.TextView;
  9. import android.widget.Toast;
  10. public class MainActivity extends AppCompatActivity {
  11. //1、定义对象
  12. ListView listView;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. //2、绑定控件
  18. listView=(ListView) findViewById(R.id.list_view);
  19. //3、准备数据
  20. String[] data={
  21. "菠萝","芒果","石榴","葡萄", "苹果", "橙子", "西瓜","菠萝","芒果","石榴","葡萄", "苹果", "橙子", "西瓜","菠萝","芒果","石榴","葡萄", "苹果", "橙子", "西瓜"};
  22. //4、创建适配器 连接数据源和控件的桥梁
  23. //参数 1:当前的上下文环境
  24. //参数 2:当前列表项所加载的布局文件
  25. //(android.R.layout.simple_list_item_1)这里的布局文件是Android内置的,里面只有一个textview控件用来显示简单的文本内容
  26. //参数 3:数据源
  27. ArrayAdapter<String> adapter=new ArrayAdapter<>(MainActivity.this,android.R.layout.simple_list_item_1,data);
  28. //5、将适配器加载到控件中
  29. listView.setAdapter(adapter);
  30. //6、为列表中选中的项添加单击响应事件
  31. listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
  32. {
  33. @Override
  34. public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
  35. String result=((TextView)view).getText().toString();
  36. Toast.makeText(MainActivity.this,"您选择的水果是:"+result,Toast.LENGTH_LONG).show();
  37. }
  38. });
  39. }
  40. }

代码解析

1.ArrayAdapter适配器

  • 1、ArrayAdapter适用亍数组或数据ArrayList(动态数组)。
  • 2、ArrayAdapter可以通过泛型来指定要适配的数据类型,然后在构造凼数中把要适配的数据传入。
  • 3、ArrayAdapter有多个构造函数的重载,可以根据实际情况选择最合适的一种。

2.点击事件响应

在这里插入图片描述

  • Parent: 指定哪个AdapterView(可能会有多个ListView,区分多个ListView)
  • View: 为你点击的Listview的某一项的内容,来源于adapter。如用((TextView)view).getText().toString(),可以取出点击的这一项的内容,转为string 类型。
  • Position: 指的是adapter的某一项的位置,如点击了listview第2项,而第2项对应 的是adapter的第2个数值,那此时position的值就为1了。注:这些数值都是从0开 始的。
  • Id:id的值为点击了Listview的哪一项对应的数值,点击了listview第2项,那id就等于1。一般和position相同。
    在这里插入图片描述

三.定制 ListView 界面

只能显示一段文本的listview太单调了,我们现在就来对listview的界面进行定制,让其丰富内容。
在这里插入图片描述

代码部分

1.布局界面 activity_main.xml 代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <ListView
  9. android:id="@+id/list_view"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"/>
  12. </LinearLayout>

2.类文件 MainActivity.java 代码:

  1. package com.example.listview2;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.widget.ListView;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class MainActivity extends AppCompatActivity {
  8. //第一步:定义对象
  9. ListView listView;
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14. //第二步:绑定控件
  15. listView = (ListView) findViewById(R.id.list_view);
  16. //第三步:准备数据
  17. List<Fruit> fruitlist = new ArrayList<>();
  18. for (int i = 0; i <2 ; i++) {
  19. Fruit pineapple=new Fruit(R.drawable.pineapple,"菠萝","¥16.9 元/KG");
  20. fruitlist.add(pineapple);
  21. Fruit mango = new Fruit(R.drawable.mango, "芒果","¥29.9 元/kg");
  22. fruitlist.add(mango);
  23. Fruit pomegranate = new Fruit(R.drawable.pomegranate, "石榴","¥15元/kg");
  24. fruitlist.add(pomegranate);
  25. Fruit grape = new Fruit(R.drawable.grape, "葡萄","¥19.9 元/kg");
  26. fruitlist.add(grape);
  27. Fruit apple = new Fruit(R.drawable.apple, "苹果","¥20 元/kg");
  28. fruitlist.add(apple);
  29. Fruit orange = new Fruit(R.drawable.orange, "橙子","¥18.8 元/kg");
  30. fruitlist.add(orange);
  31. Fruit watermelon = new Fruit(R.drawable.watermelon, "西瓜","¥28.8元/kg");
  32. fruitlist.add(watermelon);
  33. }
  34. //第四步:设计每一个列表项的子布局
  35. //第五步:定义适配器 控件 -桥梁-数据
  36. FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitlist);
  37. listView.setAdapter(adapter);
  38. }
  39. }

3.类文件 Fruit.java 代码:

  1. package com.example.listview2;
  2. public class Fruit {
  3. private int imageID;
  4. private String name;
  5. private String price;
  6. public int getImageID() {
  7. return imageID;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public String getPrice() {
  13. return price;
  14. }
  15. public Fruit(int imageID, String name, String price) {
  16. this.imageID = imageID;
  17. this.name = name;
  18. this.price = price;
  19. }
  20. }

4.类文件 FruitAdapter.java 代码:

  1. package com.example.listview2;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.ArrayAdapter;
  7. import android.widget.ImageView;
  8. import android.widget.TextView;
  9. import java.util.List;
  10. import androidx.annotation.NonNull;
  11. import androidx.annotation.Nullable;
  12. //用于将上下文、listview 子项布局的 id 和数据都传递过来
  13. public class FruitAdapter extends ArrayAdapter<Fruit> {
  14. public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
  15. super(context, resource, objects);
  16. }
  17. //每个子项被滚动到屏幕内的时候会被调用
  18. @NonNull
  19. @Override
  20. public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
  21. Fruit fruit=getItem(position);//得到当前项的 Fruit 实例
  22. //为每一个子项加载设定的布局
  23. View view=LayoutInflater.from(getContext()).inflate(R.layout.fruit_item,parent,false);
  24. //分别获取 image view 和 textview 的实例
  25. ImageView fruitimage =view.findViewById(R.id.fruit_image);
  26. TextView fruitname =view.findViewById(R.id.fruit_name);
  27. TextView fruitprice=view.findViewById(R.id.fruit_price);
  28. // 设置要显示的图片和文字
  29. fruitimage.setImageResource(fruit.getImageID());
  30. fruitname.setText(fruit.getName());
  31. fruitprice.setText(fruit.getPrice());
  32. return view;
  33. }
  34. }

5.布局界面 fruit_item.xml 代码:

  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:orientation="horizontal"
  5. android:layout_height="wrap_content">
  6. <ImageView
  7. android:id="@+id/fruit_image"
  8. android:src="@drawable/apple"
  9. android:layout_width="100dp"
  10. android:layout_height="80dp"/>
  11. <TextView
  12. android:id="@+id/fruit_name"
  13. android:layout_gravity="center_vertical"
  14. android:textSize="30sp"
  15. android:textColor="#000000"
  16. android:text="name"
  17. android:layout_marginLeft="10dp"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"/>
  20. <TextView
  21. android:id="@+id/fruit_price"
  22. android:layout_gravity="center_vertical"
  23. android:textColor="#ff0000"
  24. android:text="price"
  25. android:textSize="30sp"
  26. android:layout_marginLeft="10dp"
  27. android:layout_width="wrap_content"
  28. android:layout_height="wrap_content"/>
  29. </LinearLayout>

代码解析

1.引入动态数组ArrayList

数组的缺点
(1)数组长度固定
(2)定义数组只能指定一种数据类型

ArrayList:可以动态增加和缩减的索引序列,它是基于数组实现的list类
List<Fruit> fruitlist = new ArrayList<>();

List泛型里面既包括图片又包含文本,因此我们要定义一个Fruit类

2.Fruit类

  1. public class Fruit {
  2. private int imageID;
  3. private String name;
  4. private String price;
  5. }

在里面添加图片的id,名称和价格
然后按下Alt+Insert键添加构造方法(Constructor)和Get方法(Getter)

3.自定义适配器 控件 -桥梁-数据

为什么要自定义适配器?
原因在于,当我们想用一些其他的展现方式,或者是本案例我们需要的图文混排的呈现方式,这就需要DIY了。
1.我们定义一个自定义适配器 FruitAdapter继承ArrayAdapter。
2.自定义适配器中常用的方法:getCount、getView、getItem、getItemId。

4.inflate()方法

inflate()方法的三个参数
inflate(R.layout.fruit_item,parent,false)

1、第一个参数是布局;(自己写的)
2、第二个参数是父容器控件;
3、第三个布尔值参数表明是否连接该布局和其父容器控件,在这里的情况设置 为false,因为系统已经插入了这个布局到父控件,设置为true将会产生多余的一 个View Group。

四.提升ListView的运行效率

目前我们ListView的运行效率是很低的,因为在FruitAdapter的 getView()方法中,每次都将布局重 新加载了一遍,将快速滚动的时候, 这将会成为性能的瓶颈。
在这里插入图片描述
getView()方法中的convertView参数,用于将之前加载好的布局进行缓存,以便之 后可以进行重用。

优化方法一:

在这里插入图片描述

优化方法二:

在这里插入图片描述

代码

  1. package com.example.listview3;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.ArrayAdapter;
  7. import android.widget.ImageView;
  8. import android.widget.TextView;
  9. import java.util.List;
  10. import androidx.annotation.NonNull;
  11. import androidx.annotation.Nullable;
  12. //用于将上下文、listview 子项布局的 id 和数据都传递过来
  13. public class FruitAdapter extends ArrayAdapter<Fruit> {
  14. public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
  15. super(context, resource, objects);
  16. }
  17. @NonNull
  18. @Override
  19. public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
  20. Fruit fruit=getItem(position);//获取当前项的 Fruit 实例
  21. View view;
  22. //新增一个内部类 ViewHolder,用于对控件的实例进行缓存
  23. ViewHolder viewHolder;
  24. if (convertView==null){
  25. //为每一个子项加载设定的布局
  26. view= LayoutInflater.from(getContext()).inflate(R.layout.fruit_item,parent,false);
  27. viewHolder=new ViewHolder();
  28. //分别获取 imageview 和 textview 的实例
  29. viewHolder.fruitimage =view.findViewById(R.id.fruit_image);
  30. viewHolder.fruitname =view.findViewById(R.id.fruit_name);
  31. viewHolder.fruitprice=view.findViewById(R.id.fruit_price);
  32. view.setTag(viewHolder);//将 viewHolder 存储在 view 中
  33. }else {
  34. view=convertView;
  35. viewHolder= (ViewHolder) view.getTag();//重新获取 viewHolder
  36. }
  37. // 设置要显示的图片和文字
  38. viewHolder.fruitimage.setImageResource(fruit.getImageID());
  39. viewHolder.fruitname.setText(fruit.getName());
  40. viewHolder.fruitprice.setText(fruit.getPrice());
  41. return view;
  42. }
  43. private class ViewHolder {
  44. ImageView fruitimage;
  45. TextView fruitname;
  46. TextView fruitprice;
  47. }
  48. }

五.ListView的点击事件

ListView的滚动毕竟只是满足 了我们视觉上的效果,下面我们来学习ListView如何才能响 应用户的点击事件。

代码

  1. //第六步:listview 的点击事件
  2. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  3. @Override
  4. public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
  5. Fruit fruit= fruitlist.get(position) ;
  6. Toast.makeText(MainActivity.this,"您选择的水果是:"+fruit.getName(),Toast.LENGTH_LONG).show();
  7. }
  8. });

六.总结

在这里插入图片描述
七.参考资料
点击免费下载链接

本文来自https://blog.csdn.net/indeedes/article/details/119530068

发表评论

表情:
评论列表 (有 0 条评论,246人围观)

还没有评论,来说两句吧...

相关阅读