创新源于模仿之四:增强的ExpandableListView

 

继续讨论一下如何实现手机QQ里那个增强版的ExpandableListView效果,如下图:

 

 

Android缺省的ExpandableListView的group header无法固定在界面上,当向下滚动后,不能对当前显示的那些child 指示出它们归属于哪个group,而这一点,在iphone中的tableview就做的非常好。

 

所以,我们来做一个固定在列表上方的提示框,显示当前显示的展开的那些child归属的group信息。

 

思路:
1. 先弄一个TextView作为指示器放在ListView的上面,跟列表上缘平齐。
2. 处理列表的上下滚动回调:

  1. if(第一行是group){  
  2.  if(第二行也是group) 隐藏指示器;  
  3.  else if(第二行是第一行展开的第一个child) 显示指示器;  
  4. }  
  5. else {  
  6.  if(第二行是group 且第一行显示不完整时) 隐藏指示器;  
  7. }  

 

 

就这样了,是吧?

 

public class GroupHeaderIndicator extends TextView
 implements OnScrollListener {

@Override
 public void onScroll(AbsListView view, int firstVisibleItem,
   int visibleItemCount, int totalItemCount) {
  // TODO Auto-generated method stub

  ExpandableListView listView = (ExpandableListView)view;
  //当前第一行归属的组ID
  int gid = ExpandableListView.getPackedPositionGroup(listView.getExpandableListPosition(firstVisibleItem));
  //当前第一行的子ID
  int cid = ExpandableListView.getPackedPositionChild(listView.getExpandableListPosition(firstVisibleItem));
  //当前第二行的子ID
  int nid = ExpandableListView.getPackedPositionChild(listView.getExpandableListPosition(firstVisibleItem+1));

  BuddiesListAdapter adapter=(BuddiesListAdapter)listView.getExpandableListAdapter();

  String gtitle=(gid>-1)?adapter.getGroup(gid).toString():"";

  //如果第一行和第二行都是组header,不需要显示
  if(cid==-1 && nid==-1){
   this.setVisibility(View.GONE);
  }
  else {
   //当前真的是一个child,而且下一行是group
   if(nid==-1 && cid>=0){
    this.setVisibility(View.GONE);
    return;
   }
   this.setVisibility(View.VISIBLE);
   this.setText(gtitle);
   this.postInvalidate();
  }
 }

}

 

一切就这么简单,然后看看它放的位置是:

 

<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"

  android:padding="8.0dip"
  android:layout_weight="1.0">
  <ExpandableListView
   android:id="@id/buddies_list"
   android:scrollbars="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:layout_marginLeft="0.0dip"
   android:drawSelectorOnTop="false"
   android:scrollingCache="true"
   android:layout_weight="1.0"
   android:fastScrollEnabled="false"
   android:footerDividersEnabled="true"
   android:cacheColorHint="#00000000"
   android:groupIndicator="@drawable/expander_group"
   style="@style/Widget.ListViewGreen" mce_style="@style/Widget.ListViewGreen"
    />

 <cn.sharetop.demo.ui.GroupHeaderIndicator
  android:id="@id/buddies_group_indicator"
     android:textColor="#333333"
  android:gravity="left|center"
  android:paddingLeft="32.0dip"
  android:layout_width="fill_parent"
  android:layout_height="44.0dip"
  android:background="@drawable/expand_group_bar"
     />   

</FrameLayout>

 

<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"

  android:padding="8.0dip"
  android:layout_weight="1.0">
  <ExpandableListView
   android:id="@id/buddies_list"
   android:scrollbars="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:layout_marginLeft="0.0dip"
   android:drawSelectorOnTop="false"
   android:scrollingCache="true"
   android:layout_weight="1.0"
   android:fastScrollEnabled="false"
   android:footerDividersEnabled="true"
   android:cacheColorHint="#00000000"
   android:groupIndicator="@drawable/expander_group"
   style="@style/Widget.ListViewGreen" mce_style="@style/Widget.ListViewGreen"
    />

 <cn.sharetop.demo.ui.GroupHeaderIndicator
  android:id="@id/buddies_group_indicator"
     android:textColor="#333333"
  android:gravity="left|center"
  android:paddingLeft="32.0dip"
  android:layout_width="fill_parent"
  android:layout_height="44.0dip"
  android:background="@drawable/expand_group_bar"
     />   

</FrameLayout>

 

我为了省事,直接从TextView中派生出这个指示器,其实你可以更复杂点,从一个ViewGroup之类的东西来做出更多的效果。

 

细心的朋友可以发现了,在QQ中,当上移列表时,有一个效果是下一个group header将指示器给推出屏幕的,图省事,我没这样做,留给兄弟你去扩展了。

 

此外,反编译QQ的代码可知,其实它的实现是自己做了一个叫 IphoneTreeView的类,继承了ExpandableListView,这样做更灵活也更好,同样,如果要实现更完美的效果,还有很多事情要做的。

 

最近想学习一下iphone的开发,有点没动力继续写这个题目了。所以,只是在这儿抛砖引玉罢了,如果你们做出了更好的效果,请拿出来共享。

 

先谢谢了!

时间: 2025-01-18 18:27:33

创新源于模仿之四:增强的ExpandableListView的相关文章

创新源于模仿之一:TabActivity的美化

  今天开始一个新专题:创新源于模仿. 第一篇从TabActivity着手,一直以为Android中的TabActivity只能放在上面,只能如此丑陋,直到有一天看到"米聊". 咋一看,软件下面的那个菜单栏,觉得像是用LinearLayout+Button来实现的,但事实上,它却是一个Tab! 怎么看出来的?我就不多说了,你懂的. 下面我们来抽丝剥茧,一步步分析它的实现过程. 1.TabActivity的布局 <TabHost xmlns:android="http:/

创新源于模仿之二:美化ListView的尝试

  今天继续,模仿MIUI做那个Contacts的ListView,如下图:       其实可以这样归纳一下我们要做的事情: 1. 按首字母分组,显示一个分组的标签头. 2. 在右边做一个全字母表,可以用手指上下滑动快速选择字母分组. 3. 再做一个当前选中的那个字母的显示. 先说第一件事.我们已经了解ListView/ListAdapter组合做出一个列表界面.那么,怎么在列表中显示一些不可选且模样不同的行,在SDK提供的例子其实是有相关代码可供参考的. 相关的代码是在ListAdapter

创新源于模仿之三:实现左右两个屏幕的切换

今天第三篇,模仿UCWEB的首页,做一个可以左右滑动的双屏.   其实要实现这个效果在Android中并非难事,因为官方的Launcher已经有现成的源代码放在那儿了,就是那个Workspace.java.大家可以去http://android.git.kernel.org/ 下载.   而我们要做的事情就是分析它并精简它(毕竟我们只是打算左右滑动罢了,并不需要能创建快捷方式文件夹之类的东西,更不需要在上面拖放图标).   public class Workspace extends ViewG

创新源于模仿之六:仿iPhone的分组列表做一个配置界面

  这个效果现在很多见了,象新浪微博客户端的"我的资料",MIUI中的设置,米聊中的"名片",,,等等等等.iPhone啊,你让Android程序员伤不起.     这个功能的实现很简单,如果你想简单的话,就是一个图片和布局的问题.今天继续拿来主义,反编译一下米聊的代码,从它的res里寻找我们需要的东西.   在res/drawable-hdpi/namecard_xxxxxxx 这些图片就是我们需要的资源,小米的设计人员做的图就是精细,比新浪的好多了.   使用上

创新源于模仿之五:做一个自己的QuickAction

 有一段时间没有上来折腾这个专题了,一来项目的确紧张,二来自己一惯是很懒的. 今天想与大家分享的是一个QuickAction的东西,模样其实就是通讯录中点击头像后弹出的那个提供可操作按钮的窗口.     这个效果其实我们也用过,就是QuickContactBadge.显然,它很有意思,但是为什么只能由系统决定上面的按钮呢? 所以今天我们要做的事情就是做一个自己的QuickAction类. 第一步:收集资源 去Android的源代码网站 http://android.git.kernel.org/

创新Or模仿?浅谈“山寨”圈里的云计算

本文讲的是创新Or模仿?浅谈"山寨"圈里的云计算[IT168 评论]当我们谈起山寨的时候,往往是带有嘲弄或自嘲的成分,假装欺骗,实为恶搞."山寨"是一种由民间IT力量发起的产业现象,从山寨手机.数码产品.山寨品牌开始,近年来,"山寨"已经上升为一种文化.任何事物,一旦上升成为一种文化,也就意味着它具有着广义的文化的特征:反映着整个社会的政治和经济,同时作用于社会政治和经济,山寨也是如此. ▲图1 山寨街 云计算领域三大"寨主"

SEO外链创新加模仿才是王道

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 继上篇文章<SEO外链策略之一:养好门户博客!>发表后,很多新手加我QQ咨询关于外链怎样快速增加的技巧.说白了,增加外链的方式就那么几种,同时也可以说增加外链的方式有很多种,关键在于个人的模仿与创新,找最好的葫芦,画最好的瓢. 昨天终于把A5上关于外链的文章从07年的第一篇到现在将近500多篇的文章整个浏览了番.于是想到写篇关于增

做SEO外链创新加模仿才是王道

摘要: 继上篇文章<SEO外链策略之一:养好门户博客!>发表后,很多新手加我QQ咨询关于外链怎样快速增加的技巧.说白了,增加外链的方式就那么几种,同时也可以说增加外链的方式有很 继上篇文章<SEO外链策略之一:养好门户博客!>发表后,很多新手加我QQ咨询关于外链怎样快速增加的技巧.说白了,增加外链的方式就那么几种,同时也可以说增加外链的方式有很多种,关键在于个人的模仿与创新,找最好的葫芦,画最好的瓢. 昨天终于把站长网上关于外链的文章都整个浏览了番.于是想到写篇关于增加网站外链总结

第三代搜索亮相中国CEO年会 陈沛称创新源于信念

10月23日,2012年中国CEO年会在京举办,对新经济(310358,基金吧)周期下的市场变革和创新进行对话探讨.在大会进行的"创新与创业新思维"主题论坛中,中搜CEO陈沛发表了<创新成就梦想领先的第三代搜索>主题演讲,向与会嘉宾.商界人士和媒体朋友们介绍了未来搜索引擎的发展趋势,阐述了第三代搜索引擎的http://www.aliyun.com/zixun/aggregation/35016.html">开放模式和理念. 在随后进行的嘉宾对话环节中,主持人