Android:如何使用SectionIndexer

11

我想找到一种使用SectionIndexer而不是AlphabetIndexer的方法。我的目标是将字符串数组的元素放在部分标题上,而不是按字母排序。我还没有找到任何使用节索引器的示例代码。

这里是AlphabetIndexer的示例代码:

private AlphabetIndexer indexer;
indexer = new AlphabetIndexer(c, c.getColumnIndexOrThrow(
   DbHelper.COUNTRIES_NAME),"ABCDEFGHIJKLMNOPQRSTUVWXYZ");

是否可以将stringArray传递给AlphabetIndexer,而不是传递"ABCDEFGHIJKLMNOPQRSTUVWXYZ",这样我就可以在标题中使用"Book"、"Food"等,而不是"A"、"B"、..."Z"了?

如果不行,最好的方法是什么?如有使用SectionIndexer而不是AlphabetIndexer的示例代码,请提供参考。

感谢您的帮助。 TJ


你是想在 ListView 中仅将元素分隔开还是有其他原因需要使用 SectionIndexer? - Mircea Nistor
我想在我的Listview中创建多个部分,每个部分都有自己的标题,并且每个部分都有若干可点击的元素。当然,部分标题不应该是可点击的。 - TJ1
我正在这里做类似的事情 https://dev59.com/xeo6XIcBkEYKwwoYQiO7 - Etienne Lawlor
1个回答

12
你可以尝试编写一个自定义的ArrayAdapter,在getView(...)方法中返回“分组标题”视图,以显示头部位置。你还需要重写getViewTypeCount()以返回新视图类型的数量(在此情况下为2),并重写getItemViewType(int position)以返回当前位置的视图类型。此外,onItemClickListener应该检查所点击的项目是否是一个分组标题。这是我的自定义数组适配器:
public class ItemListAdapter extends ArrayAdapter<ModelItem>
{
    private static final int    TYPE_SECTION_HEADER = 0;
    private static final int    TYPE_LIST_ITEM  = 1;

    int mDefaultRowLayoutResID;
    Context mContext;
    LayoutInflater mInflater;
    ArrayList<ModelItem> lItems;

    public ItemListAdapter(Context context, int resource, ArrayList<ModelItem> items)
    {
        super(context, resource, items);
        mContext = context;
        mResource = resource;
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        lItems = items;
    }

    @Override
    public ModelItem getItem(int position)
    {
        return lItems.get(position);
    }

    @Override
    public int getCount()
    {
        return lItems.size();
    }

    @Override
    public int getViewTypeCount()
    {
        return 2;
    }

    @Override
    public int getItemViewType(int position)
    {
        ModelItem item = lItems.get(position);
        if (item.isHeader())
        {
            return TYPE_SECTION_HEADER;
        }
        else
        {
            return TYPE_LIST_ITEM;
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder holder;
        ModelItem item = getItem(position);

        if (convertView == null)
        {
            if (item.isHeader())
            {
                convertView = mInflater.inflate(R.layout.row_item_section_header, null);
                holder = new ViewHolder();
                holder.title = (TextView)convertView.findViewById(R.id.list_header_title);
                holder.subtitle = null;
                convertView.setTag(holder);
            }
            else
            {
                convertView = mInflater.inflate(R.layout.row_item_default, null);
                holder = new ViewHolder();
                holder.title = (TextView)convertView.findViewById(R.id.row_item_title);
                holder.subtitle = (TextView)convertView.findViewById(R.id.row_item_subtitle);
                convertView.setTag(holder);
            }
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.title.setText(item.getTitle());
        if (holder.subtitle != null)
        {
            holder.subtitle.setText(item.getSubtitle());
        }
        return convertView;
    }

    private class ViewHolder
    {
        public TextView title;
        public TextView subtitle;
        public ImageView leftIcon;
        public View rightControl;
    }
}

这是 row_item_default.xml 文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <TextView
        android:id="@+id/row_item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
    <TextView
        android:id="@+id/row_item_subtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/row_item_title"
    />
</RelativeLayout>

这是row_item_section_header.xml文件:

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_header_title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    style="?android:attr/listSeparatorTextViewStyle"
/>

ModelItem类是一个包含标题、副标题以及一个布尔值(用于判断是否为节标题)的简单容器。

这不是编写此适配器的唯一方式,但我希望这可以帮助你。


我正在尝试使用这些代码,但在接受答案之前有一些问题。@Mircea 再次感谢您的帮助:在我的先前代码中,我有一个字符串数组 "files",我使用的方式是:'setListAdapter(new ArrayAdapter<String>(this, R.layout.row, files));'。现在使用您的代码,我应该使用 ItemListAdapter 而不是 ArrayAdapter 吗?使用它的正确方法是什么?我应该有:'setListAdapter(new ItemListAdapter <String>(this, R.layout.row, files));'? - TJ1
你可以像这样使用它:setListAdapter(new ItemListAdapter <ModelItem>(this, R.layout.row, modelItems));但是你必须先从你的 files 数组构建 ArrayList<ModelItem> modelItems,并在应该放置部分标题的位置插入其他项。这个想法是让你的 ItemListAdapter 知道在哪里将行充气为部分标题,以及在哪里将其充气为普通行。 我通过创建 ModelItem 类并使其在应该是部分标题的地方响应 true,在普通行中响应 false 来实现这一点。 - Mircea Nistor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接