十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
在android开发中ListView是非常重要的控件。我自己也还是一个小白,把自己的学习经验分享出来,希望可以帮到初学Android的朋友们。这也是我第一次写博客,我尽量将结构处理的好一些,也说的易懂一些。如果写得不好或者有误,请指正见谅!
站在用户的角度思考问题,与客户深入沟通,找到瑞安网站设计与瑞安网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站设计制作、网站设计、企业官网、英文网站、手机端网站、网站推广、国际域名空间、网站空间、企业邮箱。业务覆盖瑞安地区。
简介
ListView特性是批量展示结构一样或者相似的信息并且可以滑动展示。ListView是一个组合控件,组合控件和普通控件的区别在于:
普通控件:内容和控件是一起的。
组合控件:内容跟控件是分开的。
所以使用ListView的时候要用到适配器,那什么是适配器呢,官方文档的解释是控件与数据之间的一个桥梁。如果不好理解,不要纠结,用多了自然就明白了。ListView作为一个整体的框架,而适配器则决定每一行上的内容是什么:
ListView 框架
适配器 内容
使用
简单介绍过ListView之后,我们来说下ListView的使用。
1、在Activity的布局文件中放入Listview,注意listview的高度要是match_parent 或者是固定值,这里不建议使用wrapcontent,因为这样会有requestLayout的操作,对性能有损耗。
2、准备好listview的行布局文件listview_item,作为listview每一行的显示样式。
3、准备listview的适配器,声明一个类继承BaseAdpater,实现四个方法:
//这个方法决定了listview显示内容的行数
public int getCount()
//决定listview每一行的布局以及内容,position代表是listview上面的行号。
public View getView(int position, View convertView, ViewGroup parent)
注意:·listview上的每一行要显示在界面上都必须调用getView()
·每一个已经消失在屏幕上的行,重新显示在界面都必须重新调用getView()
·如果getCount() 返回的结果为0的话,是不会调用getView()
4、getView()中每一行的布局创建以及内容设置
//获取行布局对象(通过解析行布局文件)
LayoutInflater inflater = getLayoutInflater();//得到布局转换器
View layout = inflater.inflate(R.layout.list_item, null);
//通过布局对象查找它里面控件的索引 (一定要通过行布局对象查找)很多初学者在使用ListView的时候很容易报空指针错误,就是这个原因。
TextView textView =(TextView)layout.findViewById(R.id.tv_list_item);
//通过行号查找容器里面对应的内容
String string = arrayList.get(position);
//把内容设置到布局对象里面的控件对象上面
textView.setText(string);
//返回行布局对象(而不是里面某个控件)
return layout;
5、查找Listview控件对象
ListView listView = (ListView) findViewById(R.id.listView1);
6、创建一个适配器对象
MyAdapter adapter = new MyAdapter();
7、为listview配置适配器(如果没有配置,listview里面是没有内容的)
listView.setAdapter(adapter)
这里再说明一下,行布局为多个控件,就是之前创建的listview_item,每一行都是listview_item。还要注意的是每行数据都要封装到同一个对象当中,比如都是将数据设置到listview_item里的textview上,这里再重申一遍,每一个控件的索引都必须通过行布局对象去查找。(否则就为null,运行时会报空指针异常)。
优化
讲完ListView的使用后,讲一下ListView的优化。
1、复用行布局
为什么要优化ListView呢,因为上面的写法,每一次getView()的时候都创建一个新的行布局对象,又因为Android的垃圾回收机制是不定时回收的,当数据比较多的时候,你上下滑动,ListView就不断的创建对象,轻则会造成卡顿,重则就内存溢出了。其实我们知道,如果屏幕上可以显示6行,我们准备7个布局对象就可以。如果不明白的童鞋可以想象一下,就像戏台上演行军并不需要那么多人,只要让前面走出戏台的人再从后面接上来就可以了。
复用行布局:
public View getView(int position, View convertView, ViewGroup parent)
{
View layout = null;
if(convertView == null)
{
LayoutInflater inflater = getLayoutInflater();//得到布局转换器
layout = inflater.inflate(R.layout.list_item, null);
}else
{
layout = convertView;
}
return layout;
}
说明: convertView用来保存已经创建并且消失在界面的那个行布局对象的索引。初始为null,当行布局对象消失的时候才有值
2、减少查找次数
基于复用行布局的基础上,如果每一次getView(),都要再去找行布局上的控件也是很麻烦的,因为既然是复用,之前肯定是已经找过了。这里的优化方法如下:
声明一个类,类里面的成员变量即为 行布局里面的 控件类型
a、class ViewHolder
{
//将行布局内的控件申明为该类的成员变量
ImageView p_w_picpathView;
TextView title;
TextView subTitle;
}
b、在getVIew中
public View getView(int position, View convertView, ViewGroup parent)
{
View layout = null;
ViewHolder holder = null;
if(convertView == null)
{
holder = new ViewHolder();
LayoutInflater inflater = getLayoutInflater();//得到布局转换器
layout = inflater.inflate(R.layout.list_item, null);
holder.p_w_picpathView = (ImageView) layout.findViewById(R.id.iv_list);
holder.title = (TextView) layout.findViewById(R.id.tv_list_item);
holder.subTitle = (TextView) layout.findViewById(R.id.tv_list_sub);
//标签(口袋)
layout.setTag(holder);
}else
{
layout = convertView;
//如果convertView不为空,得到holder,然后得到行布局内控件的引用。
holder = (ViewHolder) layout.getTag();
}
当然ListView的优化在实际的项目开发中在数据请求的过程中会有一些bug,这里以后再说明解决。
数据的更新
//通知适配器内容发生改变,更新界面
adapter.notifyDataSetChanged();
lisetview 行点击事件
1、设置行点击事件
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view,
int position, long id) {
Log.e("onItemClick", "position:" + position);
}
});
2、长按弹出选项菜单
//为listview注册上下文菜单
registerForContextMenu(listView);
//长按事件
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView parent, View view,
int position, long id) {
Log.e("onItemLongClick", "position:" + position);
MainActivity.this.position = position;
return false; (返回false的时候事件还会向下传递,返回true就到此结束)
}
});
当然还需重写onCreateContextMenu和onContextItemSelected方法。listvew长按弹出选项菜单还有另一种方法:
listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
// @Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
}
});
总结
好了,ListView就讲到这里了,当然要做出漂亮的listview还没那么简单,这些可能会在后面的博客中说道,希望这篇博客对大家有所帮助,谢谢!