Android ListView字母索引(仿微信通讯录列表)

来源:互联网 发布:彩票11选5遗漏数据分析 编辑:程序博客网 时间:2024/05/20 18:44

一、设计图


原理简介:

自定义一个View 继承 FrameLayout, 有3个子View: ListView(数据列表), ListView(索引字母列表), TextView(索引字母)


二、字母列表原理

    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh)    {        super.onSizeChanged(w, h, oldw, oldh);                mLetterAdapter = new LetterAdapter(h-getPaddingTop()-getPaddingBottom());        mLetterListView.setAdapter(mLetterAdapter);    }

       onSizeChanged这个方法,会在第一次布局和屏幕发生变化的时候调用,这里取到字母ListView布局后的实际高度,就是参数中的h,让LetterAdapter计算出每个字母的高度,设给字母ListView,以保证所有的字母在view大小发生改变的时候都能显示完整。

       /**         * 构造方法         *          * @param height view height         */        public LetterAdapter(int height)        {            ...            itemHeight = height/letterArray.length;        }

       而通过上图,当touch字母ListView 的时候,根据计算可以得到点击的是哪个字母,然后通过这个字母找到主ListView的对应的位置,通过主ListView的setSelection方法显示,并且把对应的字母设置到第一张图上面的TextView中。


三、主ListView的适配器设计原理



在主ListView的Adapter的构造中,1插入字母,2记录字母对应的位置(注意:传入的列表须已按着字母顺序排序好)。这样当字母列表滑动的时候,从Map中取出对应字母的位置,并显示即可。


四、使用

布局代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.justlcw.letterlistview.letter.LetterListView        android:id="@+id/letterListView"        android:layout_width="match_parent"        android:layout_height="match_parent" >    </com.justlcw.letterlistview.letter.LetterListView></RelativeLayout>

MainActivity

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState)     {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                LetterListView letterListView = (LetterListView) findViewById(R.id.letterListView);        letterListView.setAdapter(new TestAdapter());    }    /**     * 这里 使用一个简单的  NameValuePair 对象,做为测试     *@Title:     *@Description:     *@Author:Justlcw     *@Since:2014-5-13     *@Version:     */    class TestAdapter extends LetterBaseListAdapter<NameValuePair>    {        /** 字母对应的key,因为字母是要插入到列表中的,为了区别,所有字母的item都使用同一的key.  **/        private static final String LETTER_KEY = "letter";                /** 这里的数据都已经按着字母排序好了, 所以传入进来的数据也应排序好,不然会出现跳转问题.  **/        String[] dataArray = {                 "鞍山", "案场", "白宫", "白云", "白俄", "长沙", "常州", "常熟", "大厂", "大娜迦",                 "福州", "福建", "富豪", "广州", "湖南", "湖北", "胡同", "加州","加拉大", "家具",                "开门", "开始", "可能", "连接", "利用","煤化工", "密度","漫画",  "你好", "你的",                "哪些", "欧版", "排行", "贫困", "平时", "请问", "确认", "其他", "染发", "让他",                "头像", "是个", "数据", "天空", "退出", "提示", "为空", "维护", "新建", "想到",                "用户", "阅读", "知道", "这本", "足球"};                public TestAdapter()        {            super();                        List<NameValuePair> dataList = new ArrayList<NameValuePair>();            for(int i=0; i<dataArray.length; i++)            {                NameValuePair pair = new BasicNameValuePair(String.valueOf(i), dataArray[i]);                dataList.add(pair);            }            setContainerList(dataList);        }        @Override        public Object getItem(int position)        {            return list.get(position);        }        @Override        public long getItemId(int position)        {            return position;        }        @Override        public String getItemString(NameValuePair t)        {            return t.getValue();        }        @Override        public NameValuePair create(char letter)        {            return new BasicNameValuePair(LETTER_KEY, String.valueOf(letter));        }        @Override        public boolean isLetter(NameValuePair t)        {            //判断是不是字母行,通过key比较,这里是NameValuePair对象,其他对象,就由你自己决定怎么判断了.            return t.getName().equals(LETTER_KEY);        }        @Override        public View getLetterView(int position, View convertView, ViewGroup parent)        {            //这里是字母的item界面设置.            if(convertView == null)            {                convertView = new TextView(MainActivity.this);                ((TextView)convertView).setGravity(Gravity.CENTER_VERTICAL);                convertView.setBackgroundColor(getResources().getColor(android.R.color.white));            }            ((TextView)convertView).setText(list.get(position).getValue());                        return convertView;        }        @Override        public View getContainerView(int position, View convertView, ViewGroup parent)        {            //这里是其他正常数据的item界面设置.            if(convertView == null)            {                convertView = new TextView(MainActivity.this);                ((TextView)convertView).setGravity(Gravity.CENTER_VERTICAL);            }            ((TextView)convertView).setText(list.get(position).getValue());                        return convertView;        }    }}

实际效果如下

 


PS:

这里只是描述了我自己认为比较简单的实现方式,可拓展、可维护,不足之处望体谅、望指点。

(免积分源码: LetterListView )

0 0
原创粉丝点击