Kotlin实现listview
- 总的思路理解
- 1准备要显示的主界面
- 2准备要展示的自定义的listview的布局样式
- 3准备要展示数据的实体类,用于存储和取出数据展示在具体的listView的item中
- 4准备好自定义的Adapter,来展示自定义的listView布局
- 5在希望展示的主界面中,加入自定义的Adapter,从而展示自己希望的格式
- 6改进
总的思路理解
写在前面:这个listview很老了,并且功能不太强大,如果只是了解的话,建议你看,但是如果想学习的话,我的意见是不如直接学习RecyclerView更实用,功能更强大
首先如果希望在一个界面上展示一个listview的功能实现,就必须要三个元素来确定显示的功能,
- 就是显示在哪个界面上,
- 就是以什么样的形式展示,
- 就是展示什么样的数据。
在自定义的listview格式中,就需要用到自定义的Adapter来显示,因此在实现继承ArrayAdapter的时候自定义自己的展示效果时,就需要重写三个参数,也就是以上三个元素
1准备要显示的主界面
<?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"
android:orientation="vertical"
android:background="#D90A4C">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="30dp"
android:text="自定义的listview展示界面"
/>
<ListView
android:id="@+id/fruitListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
2准备要展示的自定义的listview的布局样式
<?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"
android:background="#D90A4C">
<ImageView
android:id="@+id/fruitImage"
android:layout_width="60dp"
android:layout_height="60dp"
/>
<TextView
android:id="@+id/fruitName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="40dp"
android:layout_marginLeft="10dp"
android:textColor="@color/blue"
/>
<TextView
android:id="@+id/fruitIntroduce"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:textSize="40dp"
android:textColor="@color/green"
android:layout_weight="1"/>
</LinearLayout>
3准备要展示数据的实体类,用于存储和取出数据展示在具体的listView的item中
class Fruit (var picture: Int, var name: String, var introduce: String)
4准备好自定义的Adapter,来展示自定义的listView布局
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mykotlintest.util.Fruit
//自定义一个adapter,构造方法中传入父类方法中需要的参数?
class FruitAdapter( activity:Activity, var resource:Int, data:List<Fruit>) : ArrayAdapter<Fruit>(activity,resource,data){
//此方法在单个子项滚动到屏幕的时候,会被调用
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
//就希望对每一个数据进行赋值,所以获取到listView对象,目的是对每一个自定义的属性赋值
var view=LayoutInflater.from(context).inflate(resource,parent,false)
//获取到组内元素
var fruitImage=view.findViewById<ImageView>(R.id.fruitImage)
var fruitName=view.findViewById<TextView>(R.id.fruitName)
var fruitIntroduce=view.findViewById<TextView>(R.id.fruitIntroduce)
//获取到每一个item的实例对象
var fruit=getItem(position)
//为每一个里面的列表项元素赋值
if(fruit!=null){
fruitImage.setImageResource(fruit.picture)
fruitName.text=fruit.name
fruitIntroduce.text=fruit.introduce
}
return view
}
}
5在希望展示的主界面中,加入自定义的Adapter,从而展示自己希望的格式
import android.os.Bundle
import android.os.PersistableBundle
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
import com.mykotlintest.util.Fruit
class FruitListMain : AppCompatActivity() {
private lateinit var fruitListView:ListView
//新建一个list,来存储即将展示的数据
lateinit var list: ArrayList<Fruit>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fruit_main)
//准备好数据源
initValue()
//先获取到控件的id,然后将此界面给他赋值adapter
fruitListView=findViewById(R.id.fruitListView)
//将listview进行适配!需要一个fruit适配的Adapter!需要新建一个
var fruitAdapter=FruitAdapter(this,R.layout.fruit_layout,list)
// fruitListView.adapter
fruitListView.adapter=fruitAdapter
//适配完了之后,就完成展示了,添加监听事件
fruitListView.setOnItemClickListener { adapterView, view, i, l ->
var fruit = list[i]
Toast.makeText(this,fruit.name,Toast.LENGTH_SHORT).show()
}
}
fun initValue(){
list= ArrayList<Fruit>()
for(i in 1..100){
var image=0
if(i%3==0){
image=R.drawable.ic_baseline_engineering_24
}else if(i%3==1){
image=R.drawable.ic_baseline_person_24
}else{
image=R.drawable.ic_baseline_lock_24
}
var name="姓名+${i}"
var introduce="我是第${i}名"
var fruit=Fruit(image,name,introduce)
list.add(fruit)
}
//需要准备参数
}
}
6改进
在第四步中在进行上下滑动时,需要进行不断的重新加载到界面,因此需要对其进行优化
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import com.mykotlintest.util.Fruit
//自定义一个adapter,构造方法中传入父类方法中需要的参数?
class FruitAdapter( activity:Activity, var resource:Int, data:List<Fruit>) : ArrayAdapter<Fruit>(activity,resource,data){
//内部类,用于记录每一个view的一个属性设置,为的是在获取时,不需要重新findViewById
inner class ViewStore(var fruitImage:ImageView,var fruitName:TextView,var fruitIntroduce:TextView)
//此方法在单个子项滚动到屏幕的时候,会被调用
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
//就希望对每一个数据进行赋值,所以获取到当前位置的item布局
var view:View
var viewStore:ViewStore
if(convertView==null){
view=LayoutInflater.from(context).inflate(resource,parent,false)
var fruitImage=view.findViewById<ImageView>(R.id.fruitImage)
var fruitName=view.findViewById<TextView>(R.id.fruitName)
var fruitIntroduce=view.findViewById<TextView>(R.id.fruitIntroduce)
viewStore=ViewStore(fruitImage,fruitName,fruitIntroduce)
//将内部类存储的信息与当前view进行绑定。
view.tag=viewStore
}else{
view=convertView
viewStore=view.tag as ViewStore
}
//获取到组内元素
//获取到每一个item的实例对象
var fruit=getItem(position)
//为每一个里面的列表项元素赋值
if(fruit!=null){
viewStore.fruitImage.setImageResource(fruit.picture)
viewStore.fruitName.text=fruit.name
viewStore.fruitIntroduce.text=fruit.introduce
}
return view
}
}