- 浏览: 511167 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
u010169720:
而且fragment调用back也有不需要finish的时候呢 ...
android异常:Can not perform this action after onSaveInstanc -
u010169720:
我这里就是拦截的,但是还是报了这个
android异常:Can not perform this action after onSaveInstanc -
Salijing:
IT之冕 写道 我的方法是注释掉super.onBackPre ...
android异常:Can not perform this action after onSaveInstanc -
cainiao1923:
上线毛啊,Bad request了
基于NodeJs开发的独立博客系统~~上线啦 -
cainiao1923:
不错 !!!!!!!!!!!!!!
在Android上实现Java和Js交互
探秘ListView的ConvertView以及ViewHolder原理
- 博客分类:
- Android那些事儿
最近在使用android的组件ExpandableListView,实现需求时,遇到不少奇怪的问题。
我的需求就是在ExpandableListView的父一级的view上添加两个按钮,实现添加子一级view的添加一级删除自己的功能。
自定义的layout如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout_parentView" android:layout_width="fill_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/iv_flag" android:layout_width="10dp" android:layout_height="10dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:focusable="false" /> <TextView android:id="@+id/tv_typename" android:layout_width="100dp" android:layout_height="30dp" android:layout_centerInParent="true" android:layout_marginLeft="10dp" android:focusable="false" /> <ImageButton android:id="@+id/iv_dele" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="5dp" android:src="@drawable/del" android:focusable="false"/> <ImageButton android:id="@+id/iv_add" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginRight="10dp" android:layout_toLeftOf="@id/iv_dele" android:src="@drawable/add" android:focusable="false"/> </RelativeLayout>
GroupView部分的Java代码如下:
@Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View parentView = null; if(groupViews.size()>groupPosition){ parentView = groupViews.get(groupPosition); } else { parentView = newParentView(groupPosition); groupViews.add(parentView); } return parentView; } private View newParentView(int groupPosition){ View parentView = li_parent.inflate(R.layout.list_parent_view, null); TextView textview = (TextView) parentView.findViewById(R.id.tv_typename); BigType bt = groupList.get(groupPosition); textview.setText(bt.getName()); View v_dele = parentView.findViewById(R.id.iv_dele); v_dele.setTag(bt.getName()); v_dele.setOnClickListener(new BtnDeleBigTypeListener(ct)); View v_add = parentView.findViewById(R.id.iv_add); v_add.setTag(bt.getName()); v_add.setOnClickListener(new BtnAddSmallTypeListener(ct)); return parentView; }
当Activity加载该layout后,当没有展开子一级,父一级上的两个ImageButton按钮均点击正常,可是当点开子一级后,点击两个ImageButton,均得不到立即的响应, 非得再产生了其他控件的点击事件(例如点击父一级,让其收起)后,之前点击 ImageButton的事件才会得到响应。一开始感觉是事件响应队列阻塞,可是为啥在产生新的事件后,所有的事件又会马上得到响应呢?
先做一个测试,代码见下,代码里的ViewHolder是一个自定义的类,也是后面ViewHolder模式的主要体现,这里先卖一关子...
View cache = null; @Override public View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) { ViewHolder _vh = null; if(convertView == null){ _vh = new ViewHolder(); convertView = newParentView(_vh); convertView.setTag(_vh); cache = convertView; } else { _vh = (ViewHolder) convertView.getTag(); if(cache.equals(convertView)){ Log.i(TAG, "equals old obj"); } } return convertView; }
上面代码主要就是想测试converView,究竟是拿来干什么的,google文档里头做了如此解析:
大致意思就是在重复利用此物之前要检查其是否为null!可是就没说清楚,这个convertView究竟是什么时候会存在!
现在来看看测试的结果,ExpandableListView总共有4个父节点,但是有以下三次输出结果:
这表明,ExpandableListView每次都在重画通过getGroupView拿到的View,而且只创建一次,之后都是都是同一个!这下子明白了,前面不能响应的按钮点击事件,原来是convertView这一覆盖层在搞鬼!因为我在代码里头每次都是在newPareView的,结果原来的convertView还在,结果就盖住了新的view,导致事件流分派出现问题,当再有convertView以外的事件发生,或ExpandableListView刷新,事件流恢复正常,响应也就正常了...
看来有时候真的要好好研究理解清楚API更深层次的用意才好做开发 啊!
不过话又说回来,其实ExpandableListView(包括ListView)的这个convertView是很有用的,因为ExpandableListView只是根据getGroupView返回的view去画列表,但是一般list列表的内容在同一级基本都会有共通性,只是加载的信息内容不同,所以重用convertView,可以很大程度上提升ListView的性能,特别是在加载大数据量时。这里配合ViewHolder模式,就可以更好地对久对象进行重用了!
下面是改良过得代码:
@Override public View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) { ViewHolder _vh = null; if(convertView == null){ _vh = new ViewHolder(); convertView = newParentView(_vh); convertView.setTag(_vh); } else { _vh = (ViewHolder) convertView.getTag(); } BigType bt = groupList.get(groupPosition); String name = bt.getName(); _vh.getTitle().setText(name); ImageButton _btn_dele = _vh.getBtn_dele(); _btn_dele.setTag(name); _btn_dele.setFocusable(false); _btn_dele.setClickable(true); _btn_dele.setOnClickListener(new BtnDeleBigTypeListener(ct)); ImageButton _btn_add = _vh.getBtn_add(); _btn_add.setTag(bt.getName()); _btn_add.setFocusable(false); _btn_add.setClickable(true); _btn_add.setOnClickListener(new BtnAddSmallTypeListener(ct)); return convertView; } private View newParentView(ViewHolder vh){ View parentView = li_parent.inflate(R.layout.list_parent_view, null); ImageView iv_flag = (ImageView)parentView.findViewById(R.id.iv_flag); vh.setImg_flag(iv_flag); TextView tv = (TextView) parentView.findViewById(R.id.tv_typename); vh.setTitle(tv); ImageButton btn_dele = (ImageButton) parentView.findViewById(R.id.iv_dele); vh.setBtn_dele(btn_dele); ImageButton btn_add = (ImageButton) parentView.findViewById(R.id.iv_add); vh.setBtn_add(btn_add); return parentView; }
其实ViewHolder并不是什么神奇的工具,他只是一个简单的vo,保存着父一级view上个控件的应用,方便在重用时,加载新的内容而已。
class ViewHolder { private TextView title; private ImageView img_flag; private ImageButton btn_add; private ImageButton btn_dele; public TextView getTitle() { return title; } public void setTitle(TextView title) { this.title = title; } public ImageView getImg_flag() { return img_flag; } public void setImg_flag(ImageView img_flag) { this.img_flag = img_flag; } public ImageButton getBtn_add() { return btn_add; } public void setBtn_add(ImageButton btn_add) { this.btn_add = btn_add; } public ImageButton getBtn_dele() { return btn_dele; } public void setBtn_dele(ImageButton btn_dele) { this.btn_dele = btn_dele; } }
发表评论
-
【翻译】 Android上实现文字围绕图片的布局
2014-04-09 16:31 3325在这边文章中,我将会介绍如何去实现一个在An ... -
【翻译】Android多线程下安全访问数据库
2014-04-08 11:21 11410为了记录如何线程安全地访问你的Android数 ... -
Android Robotium小结
2014-03-17 15:41 2278Robotium 是一款基于Android instrum ... -
Monkeyrunner小结
2014-03-15 23:49 6453Monkeyrunner----Android tools ... -
Android开发陷阱:利用PendingIntent传递唯一的Intent
2013-11-07 11:36 42069PendingIntent 是对真实 ... -
Android开发陷阱:利用PendingIntent传递唯一的Intent
2013-11-07 11:29 0PendingIntent 是对真实 ... -
GridView的特殊派生应用
2013-11-06 17:07 2110一、ScrollView + GridView 在Sc ... -
Android的ps命令介绍和技巧
2013-07-05 18:37 6588在Linux下,ps是非常普 ... -
在Android上实现Java和Js交互
2013-07-05 18:34 28139其实webview加载资源的速度并不慢,但是如果资源多 ... -
TextView的日常使用技巧
2013-07-05 18:29 4989Textview在日常开发工作中使用非常频繁,在这里 ... -
Android NDK开发之Jni调用Java对象
2013-03-16 00:11 26287本地代码中使用Java对 ... -
Android NDK开发之数组类型的操作
2013-03-16 00:05 8784Jni 可以通过JNIEnv提供的方法,对传过来的Java ... -
Android NDK开发之Jni的数据类型
2013-03-16 00:03 11327在前面的一篇博客《And ... -
Android NDK开发简介
2013-03-07 15:12 5867最近由于项目的 ... -
Android的NDK开发~SQLite3
2013-02-05 14:02 0What? NDK的N,即native,NDK开发,是指使 ... -
Android的NDK开发~Hellow world!
2013-02-05 13:52 24151、到Google官网下载adt- ... -
关于SD卡管理的注意事项
2013-01-18 11:24 11857问题: 本人一直有使 ... -
Activity流程控制之startActivityForResult
2012-10-18 09:48 0startActivityForResult不能与flag I ... -
Json解析之Gson库
2012-09-24 11:46 25512Json(JavaScript Object Notation ... -
搞定个性化输入提示--自定义AutoCompleteTextView
2012-09-04 14:44 4994在设计app的输入界面时,假如假如智能提示,给用户带来的不只是 ...
相关推荐
ListViewAdapter和ViewHolder代码,全面的安卓listview适配器源码。使得使用listview绑定数据显示非常方面
listview适配器,包含 ListViewAdapter和ViewHolder以及简单使用demo代码。该适配器能快速简单绑定数据和操作显示数据。可以对其扩充修改
打造万能的ListView适配器(ViewHolder+CommonAdapter)
listview优化 BaseAdapter
万能的ViewHolder
通常我们在一个项目中会多处使用到listview,我们为什么不把它抽取出来呢,这样使用起来方便一百倍,而且可以提高代码的复用率
使用了convertView和viewHolder两种优化方式,ListView的子布局是单一布局,对应的我的博客地址是: http://blog.csdn.net/u012320459/article/details/47667869
Android ListView多种布局优化demo,使用了两种优化手段,包括convertView,ViewHolder,对应的我的博客地址是: http://blog.csdn.net/u012320459/article/details/47667869
我们在使用ListView的时候,经常会使用的ViewHolder方式作为缓存,每次都需要手动的通过viewholder.icon = convertview.findVIewByid(id);一般的app都会有好几个页面会用到ListView,这样的话我们的代码量就会很大,...
通用Adapter 通用ViewHolder
这里介绍了listView的基本使用,数据源的添加,以及viewHolder机制的添加以及介绍
ListView的多种子布局优化demo,使用了convertView和viewHolder两种优化方式,对应的我的博客地址是: http://blog.csdn.net/u012320459/article/details/47667869
listView中多个listItem布局时,convertView缓存及使用
ListView布局之View复用原理举例
* listview的第一个元素(A)是公用一个convertView的(一般情况),此时问题就来了,如果异步下载图片执行的比较慢,第一个元素对应的url * 下载的图片会放到第一个元素上面还是滑动后第一个可见的元素上面呢? ...
我们知道,ListView通过使用ViewHolder来提升性能。ViewHolder通过保存item中使用到的控件的引用来减少findViewById的调用,以此使ListView滑动得更加顺畅。但这种模式在listview中即使不使用也无妨。 换言之,在...
我们知道,ListView通过使用ViewHolder来提升性能。ViewHolder通过保存item中使用到的控件的引用来减少findViewById的调用,以此使ListView滑动得更加顺畅。但这种模式在listview中即使不使用也无妨。 换言之,在...
ListView复用多个布局文件。 //复用三个布局文件 @Override public View getView(int position, View convertView, ViewGroup parent) { viewHolder1 holder1 = null; viewHolder2 holder2 = null; ...
Android listview适配器以及提升listview的效率。这是一个较标准的写法,listview的适配器,以及单击,长按的监听,或者listview里面其他控件的监听。
我们知道,ListView通过使用ViewHolder来提升性能。ViewHolder通过保存item中使用到的控件的引用来减少findViewById的调用,以此使ListView滑动得更加顺畅。但这种模式在listview中即使不使用也无妨。 换言之,在...