ListView的一些基本用法

简单用法

创建一个简单的ListView非常简单

<ListView  
    android:id="@+id/listView"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent" />

这就可以创造一个简单的ListView。

输入数据源

这里先暂时用少量数据,listof一个集合

class MainActivity : AppCompatActivity() {  
    private val data= listOf(  
        "Apple","Banana","Watermelon","Pear","Grape","Pineapple",  
        "Strawberry","Cherry","Mango"  
    )  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main)  
        val adapter = ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,data)  
        val list1 = findViewById<ListView>(R.id.listView)  
        list1.adapter = adapter  
    }  
}

数据需要通过设配器传输进ListView,最好用的设配器之一是ArrayAdapter,有多个构造函数。

这里由于数据源都是字符串,因此类型强制为String,依次传入参数。

android.R.layout.simple_list_item_1是ListView子项布局的一个id,data就是数据源。

然后将适配器传递进去即可。效果图如下

定制界面

自定义界面,我们首先需要ListView适配器的适配类型。

即需要定义一个实体类

这里我们定义了一个fruit类

class Fruit(val Name:String,val imageId:Int) {  
}

欸,可以发现不需要构造方法,因为功能只是提供一个适配类型。

参数为水果的名字和图片id。

我们的ListViewlayout已经写好了,还需要一个fruit_item,用来显示图片和文字。

<ImageView  
    android:layout_width="40dp"  
    android:layout_height="40dp"  
    android:id="@+id/fruitImage"  
    android:layout_gravity="center_vertical"  
    android:layout_marginLeft="10dp"  
    />  
<TextView  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:id="@+id/fruitName"  
    android:layout_gravity="center_vertical"  
    android:layout_marginLeft="10dp"  
    />

这里定义了两个控件,都比较简单,位置都是垂直居中。

接下来是比较重要的一步:自定义适配器

自定义的适配器将继承ArrayAdapter,并且将泛型指定为fruit类。

class FruitAdapter(avtivity:Activity,val resourceId:int,data:List<Fruit>):ArratAdapter(activity,resourceId,data){
	override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
		val view = LayoutInflater.from(context).inflate(resourceId,parent,false)
		val fruitImage = view.findViewById(R.layout.FruitImage)
		val fruitName = view.findViewByid(R.layout.FruitName)
		val fruit = getItem(position)
		if(fruit!=null)
		{
			fruitImage.setImageResource(fruit.imageId)
			fruitName.text = fruit.name
		}
		return view
	}
}

getView方法会在每个子项被滚动到屏幕的时候会被调用。

首先还是调用LayoutInflater类中的from()方法生成一个实例对象,再调用inflate动态加载,这里有三个参数,目前暂时不需要知道为什么传这三个参数,只需要知道这是ListView的标准写法即可。

getItem会得到当前的Fruit实例,当Fruit不为空时,就可以设置图片和文字。

最后需要在MainActivity中调用适配器。

  
class MainActivity : AppCompatActivity() {  
    private val fruitList = ArrayList<Fruit>()  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main)  
        initFruits()  
        val adapter = FruitAdapter(this,R.layout.fruit_item,fruitlist)
        listView.adapter = adapter
    private fun initFruits()  
    {  
        repeat(2){  
            fruitList.add(Fruit("Apple",R.drawable.apple_pic))  
            fruitList.add(Fruit("Banana",R.drawable.banana_pic))  
            fruitList.add(Fruit("Orange",R.drawable.orange_pic))  
            fruitList.add(Fruit("Watermelon",R.drawable.watermelon_pic))  
            fruitList.add(Fruit("Pear",R.drawable.pear_pic))  
            fruitList.add(Fruit("Grape",R.drawable.grape_pic))  
            fruitList.add(Fruit("Pineapple",R.drawable.pineapple_pic))  
            fruitList.add(Fruit("Strawberry",R.drawable.strawberry_pic))  
            fruitList.add(Fruit("Cherry",R.drawable.cherry_pic))  
            fruitList.add(Fruit("Mango",R.drawable.mango_pic))  
        }  
    }  
}

首先创建一个fruitlist用来收集所有的水果图片和名字,用initFruit来初始化,将图片的名字与图片i导入。

后面就是我们熟悉的操作啦。

效果如下:

优化

目前的ListView的效率非常低,还有很多地方可以改进。

比如,每次滚动时都要调用getView方法,加载所有布局,这其实是不需要的。

只需要做一点小小的变动即可

class FruitAdapter(avtivity:Activity,val resourceId:int,data:List<Fruit>):ArratAdapter(activity,resourceId,data){
	override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
		val view:View
		if(convertView==null)
		{
			view = LayoutInflater.from(context).inflate(resourceId,parent,false)
		}else
		{
			view = convertView
		}
	}
}

convertView是缓存参数,用于将之前加载好的布局缓存,如果已经缓存那就可以直接用啦。

还有比如每次都有重新用FindViewByid捕获控件,也是比较费时间,这里可以用ViewHolder提前捕获,需要用到时就可以直接调用。

class FruitAdapter(avtivity:Activity,val resourceId:int,data:List<Fruit>):ArratAdapter(activity,resourceId,data){
	inner Class ViewHolder(fruitImage:Imageview,fruitName:TextView)
	override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
		val view:View
		val viewHolder:ViewHolder
		if(convertView==null)
		{
			view = LaytoutInflater.from(context).inflate(resourceId,partent,false)
			val fruitImage = view.FindViewByid(R.id.fruitImage)
			val fruitName  = view.FindViewById(R,id.fruitName)
			viewHoler.ViewHolder(fruitName,fruitImage)
			view.tag=viewHolder
		}else
		{
			view = convertView
			viewHolder = view.tag as ViewHolder
		}
		val fruit = getItem(position)
		if(fruit != null)
		{
			viewHolder.fruitImage.setImageResource(fruit.imageId)
			viewHolder.fruitName.text = fruit.Name
		}
		return view
	}
}

这里创建了一个inner类viewHolder用来缓存控件。

这样就可以使得效率更高!

点击事件

这里学习一个setOnItemClickListener方法

setOnItemClickListener会有4个参数,但是有时候实际用到的并没有全部,因此没有用到的参数可以用’_‘表示

代码如下

listView.setOnItemClickLister{_,_,position,_ ->
	val fruit = fruitList[positon]
	Toast.maketext(this,fruit.name,Toast.LENGTH_SHORT).show()							
}
代码参考自《第一含代码第三版》——郭霖大神
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值