如何定制化 ListView 界面
😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD
如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。
😊 座右铭:不想当开发的测试,不是一个好测试✌️。
如果感觉博主的文章还不错的话,还请点赞、评论、收藏哦!👍
在上一篇文章中,我们介绍了 ListView的简单使用,只是简单的展示一段文本,现在我们开始对 ListView 界面进行定制。和网上其他案例类似,也是以水果图片为例,但本篇文章更加详细。
主要代码文件:
-
MainActivity 我们定义为 DIYListViewActivity,对应的 layout 布局文件为 activity_diylist_view.xml;
-
Fruit 实体类:用于描述水果的属性信息,对应的 layput 布局文件为 fruit_item.xml
-
FruitAdapter:自定义适配器
因为适配器是连接数据和视图的桥梁,视图是 ListView、而水果数据是数据,我们先定义一个实体类 Fruit ,作为 ListView 适配器的适配类型。
Fruit 类中有两个字段:
-
name:水果名字
-
imageId :水果图片id
class Fruit(val name:String,val imageId:Int)
在 ListView 文章中,ListView 的子项是一段文本,我们采用的是 Android 内置的布局文件,而我们定制化 ListView 界面的话,在本篇文章中 ListView 的子项水果数据,所以我们要新增一个布局文件,用于水果数据的具体展示(fruit_item.xml)。
我们还需要自定义一个适配器 FruitAdapter ,用于在 ListView 中显示水鬼,这个适配器继承 ArrayAdapter,并将范型指定为 Fruit 类,(范型:允许我们编写可以处理多种类型的代码,而不需要为每种类型编写重复的代码)
自定义适配器方法:继承现有适配器的实现类,例如 ArrayAdapter,重写 getView() 方法,在 getView() 方法中,创建一个 itemView,它是每个列表项的根视图。然后,我们通过调用 findViewById 来获取到自定义布局中的 ImageView、TextView 控件,然后,从数据源中获取对应位置的水果对象,并将水果对象的图片和名称设置给对应的视图控件,最后,返回 itemView。
class FruitAdapter (activity: Activity,val resourceId: Int,data:List):ArrayAdapter(activity,resourceId,data) { override fun getView(position: Int,convertView: View?,parent:ViewGroup):View{ val view = LayoutInflater.from(context).inflate(resourceId,parent,false) val fruitImage:ImageView = view.findViewById(R.id.fruitImage) val fruitName:TextView = view.findViewById(R.id.fruitName) val fruit = getItem(position) //获取当前项的Fruit实例 if(fruit != null){ fruitImage.setImageResource(fruit.imageId) fruitName.text = fruit.name } return view } }
详解:
-
FruitAdapter 定义了一个主构造函数,用于将 Activity 的实例,ListView子项布局和 id 和数据源传递进来。
class FruitAdapter (activity: Activity,val resourceId: Int,data:List):ArrayAdapter(activity,resourceId,data)
-
activity: Activity 是构造函数的参数,表示当前的Activity
-
val resourceId: Int 是构造函数的参数,表示列表项的布局资源 id
-
data:List 是构造函数的参数,闭表示要显示的水果数据列表
这里说的构造函数是 FruitAdapter 类的构造函数,在构造函数中,activity: Activity 参数用于接收传入的 Activity 对象,并将其传递给父类 ArrayAdapter 的构造函数。通过这种方式,FruitAdapter 类可以使用传入的 Activity 对象来执行一些与 UI 相关的操作,例如使用 LayoutInflater 创建视图、获取资源等。
-
重写 getView() 方法,用于获取指定位置上的列表项的视图。
override fun getView(position: Int,convertView: View?,parent:ViewGroup):View{ val view = LayoutInflater.from(context).inflate(resourceId,parent,false) val fruitImage:ImageView = view.findViewById(R.id.fruitImage) val fruitName:TextView = view.findViewById(R.id.fruitName) val fruit = getItem(position) //获取当前项的Fruit实例 if(fruit != null){ fruitImage.setImageResource(fruit.imageId) fruitName.text = fruit.name }
- LayoutInflater.from(context) 创建 LayoutInflater 对象,用于将布局资源转换为视图;
- inflate(resourceId,parent,false) 从指定的布局资源 ID 创建视图,parent 是父视图,false 表示不将视图附加到父视图上,即只让在父布局中声明的 layput 属性生效。
- view.findViewById() 获取视图中的 fruitImage、fruitName
- getItem(position) 方法从数据源中获取指定位置的水果对象,即获取当前项的 Fruit 实例。
if(fruit != null) 如果水果对象不为空,调用 setImageResource() 和 setText() 方法设置显示的图片和文字
- 最后,返回 设置好数据的视图 return view 。
好了,自定义适配器我们已经准备好了,接下来,我们写MainActivity中的逻辑代码
class DIYListViewActivity : AppCompatActivity() { private val fruitList = ArrayList() @SuppressLint("MissingInflatedId") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_diylist_view) initFruits() //初始化水果数据 var listView: ListView = findViewById(R.id.listView) val adapter = FruitAdapter(this,R.layout.fruit_item,fruitList) listView.adapter = adapter ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.listView)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } } // 初始化水果数据, private fun initFruits() { repeat(10){ fruitList.add(Fruit("apple", R.drawable.apple_pic)) fruitList.add(Fruit("banana", R.drawable.banana_pic)) } } } // repeat函数是kotlin中常用标准函数,
Demo 展示
至此,定制化 ListView 界面 我们已经完成啦,赶快动手实践下吧。
-
-
-