目录
3.2. 定义ListView中一栏数据(即可ListItem)的布局
一、ListView是什么
listview是一个以垂直方式在项目中显示视图的列表(即在一个窗口里可以滚动查看数据,跟你划朋友圈一样)。是一种不能实现确定视图中的内容的适配器视图(adapter view)。数据和视图的绑定,需要通过继承ListViewAdapter接口的适配器实现。确保当上下滚动的时候,能够动态刷新视图内容。通常我们都会自定义一个继承自BaseAdapter(已继承ListViewAdapter),ArrayAdapter(继承自BaseAdapter),SimpleAdapter(继承自BaseAdapter)的类,重写getView()方法,实现自己想要的功能。
listview的效果如下:(是可以上下滑动的),当上下滚动时,就通过适配器来确定到底把什么数据显示到视图当中。
二、适配器(以Base适配器为例子)
适配器就我自己来看,我觉得这是一个非常重要的知识点,Adapter是用来帮助填出数据的中间桥梁,简单点说吧:将各种数据以合适的形式显示在View中给用户看。
在创建适配器时,一般都会把一个数据集完整地输入给适配器,然后让适配器按照需求去展示需要展示给用户的数据。
2.1 适配器的常用方法(必须实现的)
2.11 getView
getView方法的作用是读取数据集中对应位置的数据,放到视图view中,并返回。
getView的定义如下:
从上图可以看到,getView方法主要包括 position、convertView、parent 三个参数:
position:从数据集中读出需要展示的某一个数据item
convertView:复用的视图view。由于getView最后的返回结果是一个view,因此如果每次调用getVeiw都要创建一个view,则会影响性能,所以当判断到缓存中有convertView,则可以直接复用这个convertView,若convertView为空,才去创建view。并且convertView往往跟ViewHolder配合使用, ViewHolder就是一个类,使用 ViewHolder 的关键好处是缓存了显示数据的视图(TextView),加快了 UI 的响应速度。在代码中,当convertView为空时,则创建一个view,并且用setTag()方法为View绑定一个存放控件的ViewHolder对象。当convertView不为空,使用getTag()方法获取convertView中绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件。
(View converView 展示在界面上的一个item。因为手机屏幕就那么大,所以一次展示给用户看见的内容的数目是固定的,如果你List中有1000条数据,不应该new1000个converView,那样内存肯定不足,应该学会控件重用,滑出屏幕的converView就在下面新进来的item中重新使用,只是修改下他展示的值)
parent:这个属性是加载xml视图时使用。inflate(R.layout.adapter__item, parent, false);确定他父控件,减少宽高的测算
使用例子如下:
getView被调用的时机:
- 初始显示时
- listview滚动时
- notifyDataSetChanged处理时 (即适配器里的数据集改变时)
2.12 getItem
官方解释是Get the data item associated with the specified position in the data set.即获得相应数据集合中特定位置的数据项。那么该方法是在哪里被调用呢?什么时候被调用呢?
通过查看源代码发现,getItem方法不是在Baseadapter类中被调用的,而是在Adapterview中被调用的。
adapterView类中,我们找到了如下方法,
那么getItemAtPosition(position) 又是什么时候被调用?答案:它也不会被自动调用,它是用来在我们设置
setOnItemClickListener、setOnItemLongClickListener、setOnItemSelectedListener的点击选择处理事件中方便地调用
来获取当前行数据的。
2.13 getItemId
当点击ListView中的一个item时,就会返回该item的编号,如下图,
我点击了张三6这一行,那么就会返回 5 。因为是从 0开始计数的。
2.14 getCount
当点击ListView时,就会触发,返回的是此适配器中数据集的数目。
三、工程项目例子
效果:(能够上下滑动查看不同的数据)
步骤:
1.首先确定主界面activity_main.xml的布局
2.定义ListView中一栏数据(即可ListItem)的布局
3. 确定ListView中 一栏数据的类型,例如这个数据由什么字段组成
4.编写适配器(用于动态给ListView视图显示数据)
5. MainActivity的逻辑编写
3.1 确定主界面activity_main.xml的布局
在一个写有”姓名“ ”年龄“ ‘班级”的栏目下 放置一个 ListView视图。这个布局文件是绘制主界面MainAcitivity的布局的。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
android:id="@+id/top"
android:layout_width="800px"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="24sp"
android:gravity="center"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="年龄"
android:textSize="24sp"
android:gravity="center"/>
<TextView
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="班级"
android:textSize="24sp"
android:gravity="center"/>
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="800px"
android:layout_height="match_parent"
android:layout_below="@+id/top"/>
</RelativeLayout>
3.2. 定义ListView中一栏数据(即可ListItem)的布局
list_item.xml:
<?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">
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="姓名"
android:gravity="center"
android:textSize="24sp"
/>
<TextView
android:id="@+id/age"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="年龄"
android:gravity="center"
android:textSize="24sp"
/>
<TextView
android:id="@+id/classview"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="班级"
android:gravity="center"
android:textSize="24sp"
/>
</LinearLayout>
3.3. 确定ListView一栏数据的字段组成
一栏数据由 姓名、年龄、班级 组成:
class Item(var name:String,var age:String,var classview:String) {
}
3.4. 编写适配器
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import com.ugc.andorid.landing.R
class ItemAdapter(var context: Context,var datas:List<Item>):BaseAdapter(){
inner class MyViewHolder{
lateinit var name:TextView
lateinit var age:TextView
lateinit var classview:TextView
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
//获取每一行的Item并显示其内容
var view:View?=null
var myHolder:MyViewHolder?=null
if(convertView==null){
myHolder = MyViewHolder()
view = LayoutInflater.from(context).inflate(R.layout.list_item,parent,false)
myHolder.name = view.findViewById(R.id.name)
myHolder.age = view.findViewById(R.id.age)
myHolder.classview = view.findViewById(R.id.classview)
view.setTag(myHolder)
}else{
view = convertView
myHolder = view.getTag() as MyViewHolder
}
myHolder.name.text = datas.get(position).name
myHolder.age.text = datas.get(position).age
myHolder.classview.text = datas.get(position).classview
return view!!
}
override fun getItem(position: Int): Any {
return datas.get(position)
}
override fun getItemId(position: Int): Long {
println(position)
return position.toLong()
}
override fun getCount(): Int {
println(datas.size)
return datas.size
}
}
3.5. MainActivity的逻辑编写
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.ugc.andorid.landing.view_class.Item
import com.ugc.andorid.landing.view_class.ItemAdapter
import kotlinx.android.synthetic.main.listview_main.*
class MainActivity: AppCompatActivity() {
//val colors = arrayOf("red","blue","black")
var itemList = mutableListOf<Item>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
inits()
listView.adapter = ItemAdapter(this,itemList)
}
private fun inits(){
for(i in 1..20){
itemList.add(Item("张三${i}","${i}","${i}"))
}
}
}