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

 

http://blog.csdn.net/sharetop/archive/2011/03/13/6246629.aspx

 

今天继续,模仿MIUI做那个Contacts的ListView,如下图:

其实可以这样归纳一下我们要做的事情:

1. 按首字母分组,显示一个分组的标签头。

2. 在右边做一个全字母表,可以用手指上下滑动快速选择字母分组。

3. 再做一个当前选中的那个字母的显示。

先说第一件事。我们已经了解ListView/ListAdapter组合做出一个列表界面。那么,怎么在列表中显示一些不可选且模样不同的行,在SDK提供的例子其实是有相关代码可供参考的。

相关的代码是在ListAdapter中这两个方法:

 

  1. @Override  
  2. public boolean areAllItemsEnabled() {  
  3.    return false//不是所有项都可选  
  4. }  
  5. @Override  
  6. public boolean isEnabled(int position) {  
  7.    return !getItem(position).name.startsWith("@section"); //如果名字以@section开头,则该项不可选  
  8. }  
 

 

简言之,在position这个项是否可选完全可以由你来控制的。

模样的问题也容易解决,只是这样做的效率会降低:

 

 

 

可以运行看看,第一个问题解决了。

第二个问题的处理就是找一张图,放在ListView的右边即可。先看看我们的Layout文件片断:

注意这个QuickAlphabeticBar是我们自定义的一个View,extends ImageButton,所以你可以先试试用ImageButton放这儿也能很快看到效果。

 

 

 

很好,这个字母表有了,因为我们需要对手指在上面滑动时的事件进行处理,所以我们自定义它,无非就是要处理这个onTouchEvent(MotionEvent event) 事件罢了,怎么处理?大家应该都想到了,就是根据手指所在位置算一下是哪个字母。

所以呢,我们先处理一下那个ListAdapter,让它implements SectionIndexer。

 

  1. public class FriendsListAdapter extends ArrayAdapter<FriendInfo> implements SectionIndexer{  
  2. private Context mContext;  
  3. private LayoutInflater mInflater;  
  4. private HashMap<String, Integer> alphaIndexer;   
  5. private String[] sections = new String[0];   
  6. public FriendsListAdapter(Context context, int textViewResourceId,  
  7. List<BuddyInfo> objects) {  
  8. super(context, textViewResourceId, objects);  
  9. mContext=context;  
  10. mInflater=LayoutInflater.from(mContext);  
  11. initSections(objects);  
  12. }  
  13. //......  
  14. @Override  
  15. public int getPositionForSection(int section)   {   
  16.           String letter = sections[section];   
  17.           return alphaIndexer.get(letter);   
  18.     }   
  19.    
  20. @Override  
  21. public int getSectionForPosition(int position)  {   
  22.         int prevIndex = 0;   
  23.         for(int i = 0; i < sections.length; i++)         {   
  24.             if(getPositionForSection(i) > position && prevIndex <= position) {   
  25.                 prevIndex = i;   
  26.                 break;   
  27.             }   
  28.             prevIndex = i;   
  29.         }   
  30.         return prevIndex;   
  31.     }   
  32. @Override  
  33. public Object[] getSections() {  
  34. return sections;   
  35. }  
  36. private void initSections(List<BuddyInfo> items){  
  37. alphaIndexer = new HashMap<String, Integer>();   
  38.         for(int i = items.size() - 1; i >= 0; i--) {   
  39.             BuddyInfo element = items.get(i);   
  40.             String firstChar = element.sortKey;//.substring(0, 1).toUpperCase();   
  41.             if(firstChar.charAt(0) > 'Z' || firstChar.charAt(0) < 'A')   
  42.                 firstChar = "#";   
  43.             alphaIndexer.put(firstChar, i);   
  44.         }   
  45.         Set<String> keys = alphaIndexer.keySet();   
  46.         Iterator<String> it = keys.iterator();   
  47.         ArrayList<String> keyList = new ArrayList<String>();   
  48.         while(it.hasNext())   
  49.             keyList.add(it.next());   
  50.         Collections.sort(keyList);   
  51.         sections = new String[keyList.size()];   
  52.         keyList.toArray(sections);   
  53. }  
  54. }  
 

 

然后,在QuickAlphabeticBar里的onTouchEvent里,我们可以快速定位到相应的段上:

 

 

 

OK了,现在我们已经解决两个问题了,但是如何显示一个小的浮动窗口提示当前选中的段的首字母呢,也不复杂,大家注意到文章开头那个Layout中的ID为fast_position的TextView了吧?就是它了。

 

 

 

这段代码就是ListView滚动时,让mDialogText显示出来,并且设置它的内容为首字母即可。关键是那个mHandler,即1秒后要记得让它隐藏起来。

就是这么多事情了,大家可以试试。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值