在Android应用程序中使用ArrayAdapter的字母排序列表视图,带有字母部分

时间:2011-12-14 07:45:30

标签: android listview sorting

我想要一个带有自定义adatper的listview,扩展ArrayAdapter,其中Type有Name字段(String)。我想对Alphabitcly项目进行排序(这不是问题)然后放入字母部分。

例如: 一个 Α 任何 ... C 儿童 ... 一世 墨水

此外 - 使用Paging从Web服务检索结果,因此当用户按下GetMoreResult按钮时,列表应相应更新 - notifyDataSetChanged将起作用吗?

5 个答案:

答案 0 :(得分:8)

我正在尝试同样的事情。我尝试使用Kasper提到的currentChar逻辑来完成它。看起来listView()调用并不总是按照您期望的顺序进行,因此效果不佳。我的解决方案是这样的:

在XML中添加一个可见性为GONE的TextView。这将是您的分隔符标记。

<TextView
    style="?android:attr/listSeparatorTextViewStyle"
    android:id="@+id/separator"
    android:layout_width="fill_parent"
    android:visibility="gone"
    android:layout_height="wrap_content"
    android:textColor="@android:color/white" />

注意:我使用Android标准分隔符样式。当然你可以自己制作。

然后使用类似

的方法向您的Adapter类添加一个布尔数组
/**
* Method takes the alphabetically sorted ArrayList as argument
*/        
private void assignSeparatorPositions(ArrayList<Items> items) {
        separatorAtIndex = new boolean[items.size()];
        char currentChar = 0;

        for (int i=0; i< items.size(); i++) {
            if ( itemss.get(i).getName().charAt(0) != currentChar ) {
                separatorAtIndex[i] = true;
            } else {
                separatorAtIndex[i] = false;
            }
            currentChar = items.get(i).getName().charAt(0);
        }

}

最后你在getView()做这样的事情:

if ( separatorAtIndex[position] ) {
            holder.sectionHeader.setText(""+name.charAt(0));
            holder.sectionHeader.setVisibility(View.VISIBLE);
        } else {
            holder.sectionHeader.setVisibility(View.GONE);
}

此方法的优点是不需要在添加单独的标题视图后跟踪项目的新位置。

答案 1 :(得分:3)

答案 2 :(得分:2)

你需要的是一个分离器。使用this guide找出如何添加分隔符。

然后在你的Adapter中,你需要一个可以告诉你字母在哪里的变量。

private Char currentChar;

getView - 方法中,您需要确定是要添加普通项还是添加分隔符。类似的东西:

if( currentItem.getCharAt( 0 ) != currentChar )
   //add a seperator.
else
   //add an item.

要记住的一件事是你可能会混淆项目的索引,因为ListView会突然包含比数组更多的项目。修复此问题的一种方法是向数组中添加虚拟项(可能只是一个空对象)。

答案 3 :(得分:1)

notifyDataSetChanged将更新列表,是的。

请记住在更新时不要重新分配列表对象,因为列表适配器会保留对您在构造时传递的引用的引用。只需清除它并在调用notifyDataSetChanged之前重新填充它。

答案 4 :(得分:0)

为了让Saad Farooq的答案适用于CursorAdapter,我在getView()中使用类似下面的hack:

String thisTitle = getStringValue(cursor, TITLE_NAME);
char thisSection = thisTitle.toUpperCase().charAt(0);
holder.sectionHeader.setText(thisSection);

holder.separator.setVisibility(View.GONE);

// Check if the previous entry was a different alphabetic character
if (cursor.moveToPrevious())
{
     String prevTitle = getStringValue(cursor, TITLE_NAME);
     char prevSection = prevTitle.toUpperCase().charAt(0);
     if (prevSection != prevTitle)
     {
        holder.separator.setVisibility(View.VISIBLE);
     }
     cursor.moveToNext();
}

请注意,有更好的方法来显示这样的分段列表,但这可以在需要时快速入侵。