expandablelistview

时间:2024-08-29 02:11:46编辑:莆田seo君

Android ExpandableListView使用小结(一)

ExpandableListView 是什么? 官方 给出的解释是: A view that shows items in a vertically scrolling two-level list. This differs from the ListView by allowing two levels: groups which can individually be expanded to show its children. The items come from the ExpandableListAdapter associated with this view. 简单翻译一下就是: 一种用于垂直滚动展示两级列表的视图,和 ListView 的不同之处就是它可以展示两级列表,分组可以单独展开显示子选项。这些选项的数据是通过 ExpandableListAdapter 关联的。 这个 ExpandableListAdapter 又是什么呢?和 ListView 使用的 BaseAdapter 差不多,都是用来给 View 提供数据、 实例化子布局的。实际使用的时候实现这个接口就可以了。 了解了这么多,我们来亲自实战一下。 到现在基本上完成了,我们来看一下运行效果~~ 在下篇文章 Android ExpandableListView使用小结(二) 中,我会分享有关 ExpandableListView 的 Indicator(指示器)的使用,欢迎各位围观~ Demo 地址: 点我飞往 GitHub~

使用ExpandableListView以及怎么优化view的显示减少内存占用

解决方案Github pull request链接:
Android的原生提供和展开分组的ListView:ExpandableListView,然而相比于iOS上原生提供的UITableView,其UI能力不足,比如没有原生的动画展开和收起效果支持。
在开源代码社区我们可以找到几个为Android的ExpandableListView添加的动画解决方案。其中idunnololz的AnimatedExpandableListView是不错的方案之一。 。它的优点:性能较好,提供源代码而不是library(这点很重要),注释清晰。
然而性能的优化是没有止境的,当分组内的子view(childView)变得复杂,或者ListView的parent结构复杂,例如内嵌与其它LinearLayout, FrameLayout或者ScrollView之中,并且parent的使用自定义的重写的onMeasure()方法时,生成childView的效率就会大大影响应用的性能。
合理使用AnimatedExpandableListView的关键是在于AnimatedExpandableListView#getRealChildView()的实现,这是应用开发的责任。实际项目中,通过优化getRealChildView(),动画效果的启动时间从1340ms减少到了680ms (展开一个含有5个子项目的分组)。而发现的问题的定位和解决方案,基本是用过使用Android提供的method tracing方法(android.os.Debug.startMethodTraceing)进行分析。
优化前的getRealChildView()实现,需要大量的view初始化,因为没有可用的convertView,而事实上,在动画绘制阶段时生成的childView完全可以被重用,及时convertView并为给出。如下面的traceview profile看到的,优化前,getChildView()消耗了超过一秒的时间。

优化后的性能:

这是如何做到的呢?这需要我们再研究一下动画展开的原理,也就是getChildView()里面耗时最长的是哪些动作。首先排除其他因素的影响,专注于AnimatedExpandableList本收得使用,我们使用GitHub上原生提供的Example来做分析:这是展开5个子项目的分组的情况,注意5个子分组的view生成,LayoutInflater.inflate被执行了10次,是其两倍。而inflate是相当耗时的。有没有方法来减少这部分工作消耗呢?

方法是使用Android推荐的LRU cache来保存childView的。关于LruCache,请见Android的reference documents和training。这里特别要注意的是,childView在dataSet改变时需要重新生成,而不是在cache中获得,这里使用的方法是判断childView的type。在自己的项目中需要根据情况认真考虑dataSet改变如何更新cache的问题。效果如下所示:inflate的次数减少到5次,一次都不浪费。消耗时间从160ms降低到80ms。


Recycleview和ListView的区别

Recycleview是ListView的更高度定制版,也可以说是升级版,当你需要高效的展示大量数据时候,动态改变元素的列表的时候,就用这个。

如果只是动态展示数据,listview也可以做到,用RecyclerView替代listview的原因有几个:

优点:

1.简介中提到的它封装了viewholder的回收复用。

2.RecyclerView使用布局管理器管理子view的位置,也就是说你再不用拘泥于ListView的线性展示方式,如果之后提供其他custom LayoutManager的支持,你能够使用复杂的布局来展示一个动态组件。

3.自带了ItemAnimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果。

4.分开的view 

缺点:

目前相对于我们对listview经常用到的方法,有下面两个问题: 

1. 不能简单的加头和尾:

不能简单的添加Head和Footer ,因为没有直接的addHead和addFoot的方法了

2. 不能简单的设置子item的点击事件:

RecycleView,会发现没有这个接口了,解决办法如下:

让你的viewholder实现onClickListener,然后在这个方法里面回调我们自己写的接口。

接着在你的Adapter里面加多个set方法,里面设置回调接口


listview和recyclerview的区别

ViewHolder
ViewHolder是用来保存视图引用的类,无论是ListView亦或是RecyclerView。只不过在ListView中,ViewHolder需要自己来定义,且这只是一种推荐的使用方式,不使用当然也可以,这不是必须的。而在RecyclerView中使用RecyclerView.ViewHolder则变成了必须,尽管实现起来稍显复杂,但它却解决了ListView面临的上述不使用自定义ViewHolder时所面临的问题。RecyclerView.ViewHolder被BaseAdapter使用,以将posiiton绑定到上面(可以通过API查看RecyclerView.ViewHolder#getPosition()方法)。
LayoutManager
我们知道ListView只能在垂直方向上滚动,Android API没有提供ListView在水平方向上面滚动的支持。或许有多种方式实现水平滑动,但是请想念我,ListView并不是设计来做这件事情的。但是RecyclerView相较于ListView,在滚动上面的功能扩展了许多。它可以支持多种类型列表的展示要求,主要如下:
1.LinearLayoutManager,可以支持水平和竖直方向上滚动的列表。
2.StaggeredGridLayoutManager,可以支持交叉网格风格的列表,类似于瀑布流或者Pinterest。
3.GridLayoutManager,支持网格展示,可以水平或者竖直滚动,如展示图片的画廊。
3.ItemAnimator
列表动画是一个全新的、拥有无限可能的维度。起初的Android API中,删除或添加item时,item是无法产生动画效果的。后面随着Android的进化,Google的Chat Hasse推荐使用ViewPropertyAnimator属性动画来实现上述需求。
相比较于ListView,RecyclerView.ItemAnimator则被提供用于在RecyclerView添加、删除或移动item时处理动画效果。同时,如果你比较懒,不想自定义ItemAnimator,你还可以使用DefaultItemAnimator。
4.Adapter
ListView的Adapter中,getView是最重要的方法,它将视图跟position绑定起来,是所有神奇的事情发生的地方。同时我们也能够通过registerDataObserver在Adapter中注册一个观察者。RecyclerView也有这个特性,RecyclerView.AdapterDataObserver就是这个观察者。ListView有三个Adapter的默认实现,分别是ArrayAdapter、CursorAdapter和SimpleCursorAdapter。然而,RecyclerView的Adapter则拥有除了内置的内DB游标和ArrayList的支持之外的所有功能。RecyclerView.Adapter的实现的,我们必须采取措施将数据提供给Adapter,正如BaseAdapter对ListView所做的那样
5.OnItemTouchListener
ListView通过AdapterView.OnItemClickListener接口来探测点击事件。而RecyclerView则通过RecyclerView.OnItemTouchListener接口来探测触摸事件。它虽然增加了实现的难度,但是却给予开发人员拦截触摸事件更多的控制权限。


如何判断expandablelistview是否处于展开状态

判断expandablelistview是否处于展开状态的方法是利用listerner监听,然后用isGroupExpanded判断即可,完整代码如下:
为listview注册如下监听
pointcategoryExpandableList.setOnGroupClickListener(new OnGroupClickListener(){
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Log.d("TAG", "POSITION: "+groupPosition);
if( parent.isGroupExpanded( groupPosition ) ){
parent.collapseGroup( groupPosition );
}else{
parent.expandGroup( groupPosition );
}
}
});


上一篇:斗战神元素神将加点

下一篇:最新浏览器