IndexableListView详解之——IndexableListViewActivity

来源:互联网 发布:淘宝卖家怎么让人直播 编辑:程序博客网 时间:2024/04/29 08:44

说明

现在app中经常使用到带索引条的列表,本系列就github上的一个实现索引列表功能的项目进行讲解。

该项目的地址为:https://github.com/woozzu/IndexableListView,大家可以下载运行一下,对项目有大概的了解。我大概说一下项目的功能:打开项目就是一个列表,快速滑动列表,右侧会显示索引条,用户点击索引条上的字符可定位到相应item,同时屏幕中间会出现索引字符的预览图,滑动索引条则预览图中字符会改变,且定位到相应item,若对索引条没有操作则索引条会隐藏。截图如下:



目录结构


可以看到,项目中有3个包,总共4个java文件,代码量不大,本系列将分别对各个java文件进行讲解。

IndexableListViewActivity:主Activity

StringMatcher:匹配列表项内容与索引字符的工具类

IndexableListView:自定义ListView,继承自ListView

IndexScroller:索引条类


IndexableListViewActivity

先贴上代码,布局文件main.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"><com.woozzu.android.widget.IndexableListView    android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:id="@+id/listview" /></LinearLayout>

IndexableListViewActivity:

<span style="font-size:10px;">public class IndexableListViewActivity extends Activity {/** * 列表数据源 */private ArrayList<String> mItems;private IndexableListView mListView;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        //添加数据        mItems = new ArrayList<String>();        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");        mItems.add("Steve Jobs");        mItems.add("Inheritance (The Inheritance Cycle)");        mItems.add("11/22/63: A Novel");        mItems.add("The Hunger Games");        mItems.add("The LEGO Ideas Book");        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");        mItems.add("Catching Fire (The Second Book of the Hunger Games)");        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");        mItems.add("Death Comes to Pemberley");        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");        mItems.add("Steve Jobs");        mItems.add("Inheritance (The Inheritance Cycle)");        mItems.add("11/22/63: A Novel");        mItems.add("The Hunger Games");        mItems.add("The LEGO Ideas Book");        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");        mItems.add("Catching Fire (The Second Book of the Hunger Games)");        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");        mItems.add("Death Comes to Pemberley");        //将item排序        Collections.sort(mItems);        ContentAdapter adapter = new ContentAdapter(this,                android.R.layout.simple_list_item_1, mItems);                mListView = (IndexableListView) findViewById(R.id.listview);        mListView.setAdapter(adapter);        mListView.setFastScrollEnabled(true);    }        /**     * 自定义适配器,继承自ArrayAdapter     *      * @illustration 其中getCount和getItem都是ArrayAdapter的方法<p>     * getCount:获得item的个数<p>     * getItem:获得对应下标item的内容     */    private class ContentAdapter extends ArrayAdapter<String> implements SectionIndexer {    private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";public ContentAdapter(Context context, int textViewResourceId,List<String> objects) {super(context, textViewResourceId, objects);}//根据索引,获得对应item的位置@Overridepublic int getPositionForSection(int section) {//如果该索引没有对应的item,则选择上一个索引,一直到第一个索引for (int i = section; i >= 0; i--) {//遍历每一个itemfor (int j = 0; j < getCount(); j++) {if (i == 0) {//i==0即索引为"#",查找以数字开头的itemfor (int k = 0; k <= 9; k++) {//匹配字符,传入参数为:item内容的第一个字符,数字if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))return j;}} else {//匹配字符,传入参数为:item内容的第一个字符,索引字符if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(mSections.charAt(i))))return j;}}}return 0;}//根据item获取索引位置,本项目没有使用到该功能@Overridepublic int getSectionForPosition(int position) {return 0;}/** * 获得存放索引字符的数组,即{"#","A","B",...,"Z"}<p> * 在IndexScroller中使用到 */@Overridepublic Object[] getSections() {String[] sections = new String[mSections.length()];for (int i = 0; i < mSections.length(); i++)sections[i] = String.valueOf(mSections.charAt(i));return sections;}    }}</span>

讲解

代码中已经添加了很多注释,下面详细讲解一下。

1.因为项目主要是实现索引功能,所以列表界面比较简单,使用ArrayList<String>设置数据,使用ArrayAdapter作为适配器,item布局使用系统自带的布局android.R.layout.simple_list_item_1。

2.注意mListView.setFastScrollEnabled(true);这一句,在IndexableListView类中重写了setFastScrollEnabled这个方法,传入true会初始化IndexScroller类的对象,在后来操作中才会显示索引条;传入false,将IndexScroller类的对象置为null,以后不显示索引条。

3.自定义适配器继承自ContentAdapter,要注意实现了SectionIndexer接口,SectionIndexer中有3个方法:①getPositionForSection  ②getSectionForPosition  ③getSections

4getPositionForSection方法中,使用两重循环来获取对应item的位置。第一重循环,是从当前索引位置一直到第一个索引位置。第二重循环,遍历每一个item,匹配item内容的第一个字符和索引字符,若匹配则返回该item的位置。

5.本项目没有用到根据item获取索引位置的功能,所以getSectionForPosition方法中没有实现相关功能。


IndexableListViewActivity的讲解就到这里啦,可能不是很清晰,请大家谅解。接下来的博客会继续讲解该项目中的其他文件,请大家多多关注哈,谢谢。



0 0
原创粉丝点击