1.ListView和Adapter
- 1)ListView就是一个能数据集合以动态滚动的方式展示到用户界面上的View,即:以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。
- 2)ListView和数据是分开的,不直接接触。而是通过Adapter(适配器)加载到屏幕。也就是说Adapter相当于是数据和View之间的桥梁。Adapter负责为每一个数据项制作View。
2.ListView工作原理
- 1)在运行时ListView会针对数据项向Adapter要View,从而来加载到界面上,那么,难道每一个item,Adapter都会重新创建一个视图吗?答案很明显是不可能的。
- 2)为了能够更快更省空间的显示,Android准备了一个叫做Recycler(循环)的组件。假如你的屏幕只能显示七个item。那么ListView只会创建八个item的视图。当第一个item出去,离开屏幕的时候,这个item的view就会被拿来重用,显示下一个item的内容。
3.继承BaseAdapter来使用ListView
- 1)BaseAdapter是个抽象类,继承它能很方便的来使用ListView
步骤: - 2)MyDataAdapter extends BaseAdapter继承适配器类
- 3)添加数据源引用
计数器:counter = 0
数据源:List mData = null;
- 1)BaseAdapter是个抽象类,继承它能很方便的来使用ListView
//上下文:Context mContext = null
//构造函数,两个参数一个上下文,一个数据源,一个计数器设置
//覆写如下回调函数
//1.数据源中的数据对象个数
public int getCount() {
return mData.size();
}
//2.指定位置处的具体数据源对象
public Object getItem(int position) {
return mData.get(position);
}
//3.数据源对象的Id,如果数据源对象自己没有定义Id,则可以简单地返回其在数据源中的位置
public long getItemId(int position) {
return position;
}
//4.每当Android ListView需要显示一行时,它会调用此方法,这里面存在四个逻辑
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(TAG, "显示:" + position + "行,调用getView()" + "参数convertView==null?" + (convertView == null));
View rootView = null;
//1)如果没有可以重用的控件,convertView为空,加载布局创建View,convertView 本质就是一个View缓冲器
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
rootView = inflater.inflate(R.layout.my_list_item, parent, false); //加载布局,创建View
rootView.setTag(position);
Log.d(TAG, "实例化rootView,保存到Tag中的值为:" + position);
counter++;
Log.d(TAG, "控件实例化个数:" + counter);
} else {
//2)控件己经被创建过,直接重用,若不空,则直接通过position,获取list中的item,直接替换view中的内容。
rootView = convertView;
}
//3)依据位置提取相应的数据源对象
MyDataClass item = mData.get(position);
//4)获取用于显示内容的控件的引用,findViewById()这个函数执行代价很大。所以不建议用这种方式,每次都加载控件
TextView titleTextView = (TextView) rootView.findViewById(R.id.tvTitle);
TextView detailTextView = (TextView) rootView.findViewById(R.id.tvDetail);
//5)设置显示内容
titleTextView.setText(item.getTitle());
detailTextView.setText(item.getDetail() + " 本行Tag中保存的值为:" + rootView.getTag());
return rootView;
}
}
- 4.优化之ViewHolder设计模式
- 1)创建一个内部类ViewHolder保存控件 holder view inside,只加载View的时候使用findViewById()方法
- 2)Tags can also be used to store data within a view without
resorting to another data structure.使用View的setTag()方法保存ViewHolder。当convertView不为空的时候,直接取出来即可.
public View getView(int position, View convertView, ViewGroup parent) { //1.回调方法中创建一个ViewHolder内部类,其外部方法体中获取其引用
ViewHolder holder=null;
View rootView=convertView;
if(convertView==null){
LayoutInflater layoutInflater = LayoutInflater.from(context);
rootView = layoutInflater.inflate(R.layout.phoneinfo_item, parent, false);
//2.加载新布局,初始化ViewHolder,并保存控件
holder=new ViewHolder();
holder.nameText= (TextView) rootView.findViewById(R.id.nameText);
holder.numberText= (TextView) rootView.findViewById(R.id.numberText);
//3.ViewHolder缓存控件数据引用,也是数据,控件类型的,需要view.setTag设置
rootView.setTag(holder);
}
else {
holder= (ViewHolder) rootView.getTag();
}
PhoneInfo phoneInfo = phoneInfoList.get(position);
//4.使用ViewHolder中保存的控件类 进行操作
holder.nameText.setText(phoneInfo.getPhoneName());
holder.numberText.setText(phoneInfo.getPhoneNumber());
return rootView;
}
// 写一个私有ViewHolder类,里面存放控件签名
private static class ViewHolder {
public TextView nameText =null;
public TextView numberText=null;
}
- 5.含有多种视图的布局ListView
- 1)如果你要加载多种布局那么首先你一定重写这两个方法,注意!type一定要从0开始!!
@Override
public int getItemViewType(int position) {
BaseModel baseModel=models.get(position);
int type=baseModel.getType();
return type;
}
@Override
public int getViewTypeCount() {
return 2;
}
2)有几个布局,就定义几个布局类,一个基类,弄多个ViewHolder保存即可。
6.ListView的属性
http://blog.youkuaiyun.com/p106786860/article/details/10596339
原图,不添加任何属性:
1)属性一:android:stackFromBottom=”true”//在ListView和GridView中使用,使它们的内容从底部开始显示。
2)属性二:
android:stackFromBottom=”true”
android:transcriptMode=”alwaysScroll”
android:transcriptMode属性:设置列表的transcriptMode模式,该模式指定列表添加新的选项的时候,是否自动滑动到底部,显示新的选项。
disabled:取消transcriptMode模式,默认的
normal:当接受到数据集合改变的通知,并且仅仅当最后一个选项已经显示在屏幕的时候,自动滑动到底部。
alwaysScroll:无论当前列表显示什么选项,列表将会自动滑动到底部显示最新的选项。- 3)属性三:android:divider属性:列表之间绘制的颜色或者图片。一般开发中用于分隔表项。
在实际开发过程中,如果你不想要列表之间的分割线,可以设置属性为@null
android:divider=”@null” - 4)属性四:
android:fadingEdge属性:设置列表的阴影
android:cacheColorHint属性:该属性在官方文档和个资料中找不到比较好的描述;根据实际的体验,当你设置的ListView的背景时,应该设置该属性为“#00000000”(透明),不然在滑动的时候,列表的颜色会变黑或者背景图片小时的情况!
1. android:cacheColorHint="#000000ff"
2. android:fadingEdge="vertical"
3. android:fadingEdgeLength="40dp"
5)属性五:fastScrollEnabled属性:启用快速滑动条,它能快速的滑动列表。但在实际的测试中发现,当你的数据比较小的时候,是不会显示快速滚动条。
android:fastScrollEnabled=”true”
7.android: ListView的OnItemClickListener详解
参考文档:http://blog.iamzsx.me/show.html?id=1470018.Android中的Adapter 详解三部曲
http://blog.youkuaiyun.com/tianfeng701/article/details/75578199.Android listview下拉刷新的实现原理及代码–Android事件传递原理的实践
http://blog.youkuaiyun.com/erjizi/article/details/4979684910.Android经常遇到Scrollview嵌套Listview造成listview无法滚动
http://blog.youkuaiyun.com/timmobile/article/details/4917981711.Android listview addHeaderView 和 addFooterView 详解
https://software.intel.com/zh-cn/node/537268
http://blog.youkuaiyun.com/avenleft/article/details/733406012.当我们使用listView的时候,拉到顶,或是拉到底部的时候,我们会发现有系统自带的阴影效果出现,android:overScrollMode=”never” 去掉系统自带的阴影效果
http://www.cnblogs.com/sosoft/archive/2013/12/16/3477575.html