Kotlin实现学习ListView(Adapter的使用)

  • Post author:
  • Post category:其他




总的思路理解

写在前面:这个listview很老了,并且功能不太强大,如果只是了解的话,建议你看,但是如果想学习的话,我的意见是不如直接学习RecyclerView更实用,功能更强大


本文学习自郭神的《第一行代码》第三版,仅作为学习后理解整理的的一个思路记忆

首先如果希望在一个界面上展示一个listview的功能实现,就必须要三个元素来确定显示的功能,

  1. 就是显示在哪个界面上,
  2. 就是以什么样的形式展示,
  3. 就是展示什么样的数据。

在自定义的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
        }
}




版权声明:本文为m0_56184347原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。