几乎所有的应用程序都会用到LlistView这个控件它允许用户通过手机上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据会滚出屏幕。本篇是入门知识,大神勿喷哦~我们会讲它的几个方面:
ListView怎么使用
ListView的优化
给ListView注册事件
ListView的原理分析
ListView的使用:
1.编写主界面布局文件
相当布局中就一个listview控件,设置高,宽和id
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=";
xmlns:tools="; android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.exam;>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
2.编写列表项的布局文件
这里使用线性布局,只有一个textview和一个imageview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=";
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/a1" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/erha" />
</LinearLayout>
3.准备数据源
//模拟数据源,实际开发中由数据库查询得来,这里用list替代
private List<Dog> list = new ArrayList<Dog>();
//初始化数据源
public void initList() {
li(new Dog("二哈的世界你不懂", R.drawable.a1));
li(new Dog("我是哈士奇", R.drawable.a2));
li(new Dog("别说我逗", R.drawable.a3));
li(new Dog("admin", R.drawable.a4));
li(new Dog("我都起来我自己都怕", R.drawable.a5));
li(new Dog("汪汪。。。。", R.drawable.a6));
li(new Dog("哦,哦,哦~", R.drawable.a7));
li(new Dog("狗狗", R.drawable.a8));
li(new Dog("没想到你是这样的二哈", R.drawable.a9));
}
这里会用到dog的数据,我们单独编写一个bean
/**
* Dog实体类
* 封装对象数据
* 要实现Serializable接口
* */
public class Dog implements Serializable {
public String name;//名称
public int img;//图片
/**
* 构造方法
* */
public Dog(String name, int img) {
= name;
= img;
}
}
4.编写适配器优化,优化适配器
/**
* 编写自己的适配器
* 适配器继承关系:
* BaseAdapter implements ListAdapter, SpinnerAdapter
* ListAdapter extends Adapter
* SpinnerAdapter extends Adapter
* */
public class MyAdatper extends BaseAdapter {
private List<Dog> list;
//构造方法,用来传递数据源
public MyAdatper(List<Dog> list) {
= list;
}
@Override
public int getCount() {
return li();
}
@Override
public Object getItem(int position) {
return li(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获得lisetView列表项,当数据成千上万时不可能每个列表项都要实列化到内存,
//其实只需要实例化一次就行,以后用到去内存中拿。借助convertView这个参数,也是google官方推荐的优化方式
//定义控件变量
View v;//列表项
TextView textView = null;//名称
ImageView imageView = null;//图片
ViewHolder viewHolder = null;//封装作用
if (convertView == null) {//convertView 为空时,初始化控件
v = View.inflate, R.layout.activity_t01item, null);//将xml文件实例化到内存称为对象
textView = (TextView) v.findViewById);
imageView = (ImageView) v.findViewById(R.id.imageView);
//进行封装(方便加入converView所以封装)
viewHolder = new ViewHolder();
viewHolder.imageView = imageView;
viewHolder.textView = textView;
//添加到listview
li(viewHolder);
} else {//convertView 不为空时,从内存中取出控件
v = convertView;
viewHolder = (ViewHolder) li();
textView = viewHolder.textView;
imageView = viewHolder.imageView;
}
//给控件添加数据
(li(position).name);
imageView.setImageResource(li(position).img);
return v;//返回列表项
}
}
这里为了优化用以个ViewHolder封装控件
/**
* 封装类,记录Listview项
*/
class ViewHolder {
public TextView textView;
public ImageView imageView;
}
5.给listview适配数据
//创建适配器
MyAdatper myAdapter = new MyAdatper(list);
//listview添加适配器,适配数据
//注:listview是一个可以放任何数数据的控件,为了通用性,所以不直接将数据添加进listview,
//而是通过中间一个adaper适配器封装一下,增加通用性.
li(myAdapter);
6.给listview注册事件
li(new Ada() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
Log.i("msg","可以");//日志打印
//这里写你的逻辑代码就可以了
Toa,li(position).name,Toa).show();
}
});
上边是listview的使用方法,整个activity的源代码如下:
package com.exam;
import android.os.Bundle;
import android.;
import android.u;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.u;
import java.u;
/**
* ListView 的使用练习,优化过的.
* ListView 允许用用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,
* 同时屏幕上原有的数据则会滚出屏幕外
* 步骤:
* 1.创建主布局文件,添加listview控件
* 2.创建listview的列表项布局文件。
* 3.编写适配器,给listview添加数据需要用适配器做适配。因为数据的类型是多种多样的。适配器会比较方便
* 4.listview的优化
* 5.给listview添加事件处理机制
*/
public class T01 extends AppCompatActivity {
private ListView listView;//声明listview
//模拟数据源,实际开发中由数据库查询得来,这里用list替代
private List<Dog> list = new ArrayList<Dog>();
//初始化数据源
public void initList() {
li(new Dog("二哈的世界你不懂", R.drawable.a1));
li(new Dog("我是哈士奇", R.drawable.a2));
li(new Dog("别说我逗", R.drawable.a3));
li(new Dog("admin", R.drawable.a4));
li(new Dog("我都起来我自己都怕", R.drawable.a5));
li(new Dog("汪汪。。。。", R.drawable.a6));
li(new Dog("哦,哦,哦~", R.drawable.a7));
li(new Dog("狗狗", R.drawable.a8));
li(new Dog("没想到你是这样的二哈", R.drawable.a9));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
(savedInstanceState);
setContentView);
//初始化数据源
initList();
//初始化ListView
listView = (ListView) );
//创建适配器
MyAdatper myAdapter = new MyAdatper(list);
//listview添加适配器,适配数据
//注:listview是一个可以放任何数数据的控件,为了通用性,所以不直接将数据添加进listview,
//而是通过中间一个adaper适配器封装一下,增加通用性.
li(myAdapter);
li(new Ada() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
Log.i("msg","可以");//日志打印
//这里写你的逻辑代码就可以了
Toa,li(position).name,Toa).show();
}
});
}
/**
* 编写自己的适配器
* 适配器继承关系:
* BaseAdapter implements ListAdapter, SpinnerAdapter
* ListAdapter extends Adapter
* SpinnerAdapter extends Adapter
* */
public class MyAdatper extends BaseAdapter {
private List<Dog> list;
//构造方法,用来传递数据源
public MyAdatper(List<Dog> list) {
= list;
}
@Override
public int getCount() {
return li();
}
@Override
public Object getItem(int position) {
return li(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获得lisetView列表项,当数据成千上万时不可能每个列表项都要实列化到内存,
//其实只需要实例化一次就行,以后用到去内存中拿。借助convertView这个参数,也是google官方推荐的优化方式
//定义控件变量
View v;//列表项
TextView textView = null;//名称
ImageView imageView = null;//图片
ViewHolder viewHolder = null;//封装作用
if (convertView == null) {//convertView 为空时,初始化控件
v = View.inflate, R.layout.activity_t01item, null);//将xml文件实例化到内存称为对象
textView = (TextView) v.findViewById);
imageView = (ImageView) v.findViewById(R.id.imageView);
//进行封装(方便加入converView所以封装)
viewHolder = new ViewHolder();
viewHolder.imageView = imageView;
viewHolder.textView = textView;
//添加到listview
li(viewHolder);
} else {//convertView 不为空时,从内存中取出控件
v = convertView;
viewHolder = (ViewHolder) li();
textView = viewHolder.textView;
imageView = viewHolder.imageView;
}
//给控件添加数据
(li(position).name);
imageView.setImageResource(li(position).img);
return v;//返回列表项
}
}
/**
* 封装类,记录Listview项
*/
class ViewHolder {
public TextView textView;
public ImageView imageView;
}
}
运行截图(我用的模拟器,这个还好,genymotion模拟器也不错)
最后聊一下listview的使用原理:
继承树结构
系统要绘制ListView了,他首先用getCount()函数得到要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(这个看实际情况,如果是一个简单的显示则是View,如果是一个自定义的里面包含很多控件的时候它其实是一个ViewGroup),然后再实例化并设置各个组件及其数据内容并显示它。好了,绘制完这一行了。那 再绘制下一行,直到绘完为止。我们写的代码是谷歌官方推荐的优化方式,系统只有第一次初始化时实例化每个控件,然后等不用了(item滑出屏幕)放入内存,由垃圾回收机制控制。再次使用时直接调用convertView引用,得到对象,进行操作。这样即使成千上万的数据量也能从容显示了,这也是为什么把适配数据交给成员员来做。提高了通用性和灵活性。觉得写还行的记得点赞哦~大神勿喷,我们说的是入门级。黄铜段位咱就不搞钻石的套路了。哈哈