http://blog.csdn.net/sharetop/archive/2011/03/13/6246629.aspx
今天继续,模仿MIUI做那个Contacts的ListView,如下图:
其实可以这样归纳一下我们要做的事情:
1. 按首字母分组,显示一个分组的标签头。
2. 在右边做一个全字母表,可以用手指上下滑动快速选择字母分组。
3. 再做一个当前选中的那个字母的显示。
先说第一件事。我们已经了解ListView/ListAdapter组合做出一个列表界面。那么,怎么在列表中显示一些不可选且模样不同的行,在SDK提供的例子其实是有相关代码可供参考的。
相关的代码是在ListAdapter中这两个方法:
- @Override
- public boolean areAllItemsEnabled() {
- return false; //不是所有项都可选
- }
- @Override
- public boolean isEnabled(int position) {
- return !getItem(position).name.startsWith("@section"); //如果名字以@section开头,则该项不可选
- }
简言之,在position这个项是否可选完全可以由你来控制的。
模样的问题也容易解决,只是这样做的效率会降低:
可以运行看看,第一个问题解决了。
第二个问题的处理就是找一张图,放在ListView的右边即可。先看看我们的Layout文件片断:
注意这个QuickAlphabeticBar是我们自定义的一个View,extends ImageButton,所以你可以先试试用ImageButton放这儿也能很快看到效果。
很好,这个字母表有了,因为我们需要对手指在上面滑动时的事件进行处理,所以我们自定义它,无非就是要处理这个onTouchEvent(MotionEvent event) 事件罢了,怎么处理?大家应该都想到了,就是根据手指所在位置算一下是哪个字母。
所以呢,我们先处理一下那个ListAdapter,让它implements SectionIndexer。
- public class FriendsListAdapter extends ArrayAdapter<FriendInfo> implements SectionIndexer{
- private Context mContext;
- private LayoutInflater mInflater;
- private HashMap<String, Integer> alphaIndexer;
- private String[] sections = new String[0];
- public FriendsListAdapter(Context context, int textViewResourceId,
- List<BuddyInfo> objects) {
- super(context, textViewResourceId, objects);
- mContext=context;
- mInflater=LayoutInflater.from(mContext);
- initSections(objects);
- }
- //......
- @Override
- public int getPositionForSection(int section) {
- String letter = sections[section];
- return alphaIndexer.get(letter);
- }
- @Override
- public int getSectionForPosition(int position) {
- int prevIndex = 0;
- for(int i = 0; i < sections.length; i++) {
- if(getPositionForSection(i) > position && prevIndex <= position) {
- prevIndex = i;
- break;
- }
- prevIndex = i;
- }
- return prevIndex;
- }
- @Override
- public Object[] getSections() {
- return sections;
- }
- private void initSections(List<BuddyInfo> items){
- alphaIndexer = new HashMap<String, Integer>();
- for(int i = items.size() - 1; i >= 0; i--) {
- BuddyInfo element = items.get(i);
- String firstChar = element.sortKey;//.substring(0, 1).toUpperCase();
- if(firstChar.charAt(0) > 'Z' || firstChar.charAt(0) < 'A')
- firstChar = "#";
- alphaIndexer.put(firstChar, i);
- }
- Set<String> keys = alphaIndexer.keySet();
- Iterator<String> it = keys.iterator();
- ArrayList<String> keyList = new ArrayList<String>();
- while(it.hasNext())
- keyList.add(it.next());
- Collections.sort(keyList);
- sections = new String[keyList.size()];
- keyList.toArray(sections);
- }
- }
然后,在QuickAlphabeticBar里的onTouchEvent里,我们可以快速定位到相应的段上:
OK了,现在我们已经解决两个问题了,但是如何显示一个小的浮动窗口提示当前选中的段的首字母呢,也不复杂,大家注意到文章开头那个Layout中的ID为fast_position的TextView了吧?就是它了。
这段代码就是ListView滚动时,让mDialogText显示出来,并且设置它的内容为首字母即可。关键是那个mHandler,即1秒后要记得让它隐藏起来。
就是这么多事情了,大家可以试试。