Android 类iphone的Expandable List View

来源:互联网 时间:1970-01-01

最近看到一些应用实现了iphone一样的Expandable ListView。如QQ for pad。本文探索和实现了相关的效果,一并附上源代码。欢迎实现和提交建议。

先看看实现的效果图:     

  • 布局设计

开始我采用的是一般的拖曳方面来做,也就是通过WindowManage创建一个顶层的窗口,然后实时更新这个窗口。但是仔细分析一下,发现这样做有些弊端:首先,如果Expandable List如果可以拖曳的话,再要跟这个top window进行同步就不好处理了。其次,拖曳的处理方面需要获得被拖曳对象的缓存图片,而本文设计的情况在从下往上滑的时候有可能处理的对象还没有画处理,这样就无从有缓存图片了。

好吧,不必把事情想得这么复杂,要什么高级的拖曳手段来实现。简单点,看下面的布局: 

 1 <RelativeLayout android:layout_width="match_parent"

2 android:id="@+id/relativeLayout1" android:layout_height="0dp"

3 android:layout_weight="10">

4 <ExpandableListView android:layout_height="wrap_content"

5 android:layout_width="match_parent" android:id="@+id/expandableListView" 6 android:layout_alignParentTop="true" android:layout_alignLeft="@+id/linearLayout1"></ExpandableListView>
7 <LinearLayout android:layout_height="wrap_content"
8 android:layout_width="match_parent" android:id="@+id/topGroup"
9 android:orientation="vertical" android:layout_alignParentTop="true"
10 android:layout_alignParentLeft="true"
11 android:background="@drawable/group_bg"></LinearLayout>
12 </RelativeLayout>

用一个RelativeLayout把两个布局重叠在一起,LinearLayout覆盖在ExpandableList上面。效果看总体效果图图 

  •  获取滑动的状态和位置

下面要解决的一个问题是,这IndicatorGroup位置是可变的,当本分组快要显示完得时候,有一个上移的过程。所以要及时的更新它的位置。研究完ExpandableListView的API,我决定使用listView.setOnScrollListener(this);通过监听这个事件,可以及时更新位置

 

  • 算法的逻辑

List view的(0,0)点所在的group的内容显示在Indicator Group上

Indicator Group的bottom不能超过,所在分组的bottom,换句话说,不能覆盖到下一个分组的top线。计算方法是获得(0,indicatorGroupHeight)所在的Group,如果和Indicator Group不同一个分组,就获得它的top位置,也就是图中的A点。这就可以计算出来Indicator 应该向上margin多少了

 

  • 总结

这里简单实现了思路,在实际使用中,不同的情况还出现一些问题,需要另外找方法解决。代码附上 (如果下载不了,请留言)

 

  • 重要的API:

pointToPosition 通过指定的点,返回list的position

getExpandableListPosition

ExpandableListView.getPackedPositionChild

ExpandableListView.getPackedPositionGroup

通过上面的函数,可以在Expandablelist和普通list中自由转换。也就是说,在Expandable list在绘图的时候,是先转换成为普通的List的。明白这个道理对解决ExpandableListView的问题有帮助。


相关阅读:
Top