【问题标题】:Alphabetical sorted listview with Alphabetic section using ArrayAdapter in Android application在 Android 应用程序中使用 ArrayAdapter 按字母顺序排序的列表视图和字母部分
【发布时间】:2014-01-12 11:34:58
【问题描述】:

我想要一个带有自定义adatper 的列表视图,扩展了ArrayAdapter,其中Type 具有名称字段(字符串)。我想按 Alphabitcly 对项目进行排序(这不是问题),然后放入 Alphabetic 部分。

例如: 一个 Α 任何 ... C 孩子 ... 我 墨水

另外 - 结果是使用分页从 web 服务中检索的,因此当用户按下 GetMoreResult 按钮时,列表应该相应更新 - notifyDataSetChanged 会起作用吗?

【问题讨论】:

标签: android listview sorting


【解决方案1】:

我也在尝试同样的事情。我尝试使用 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 标准分隔符样式。当然你也可以自己做。

然后使用类似这样的方法向您的适配器类添加一个布尔数组

/**
* 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);
}

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

【讨论】:

    【解决方案2】:

    【讨论】:

    • 此示例不按字母顺序对项目进行排序。检查来源。
    • 非常感谢。会试试的。看起来很有趣 - 我会自己进行分类。这不是问题
    • 在 listItemObject 构造函数中将此代码排序,不区分上下。字符 c = name.charAt(0);字符 c1 = Character.toUpperCase(c); name = name.replaceFirst(c.toString(), c1.toString());this.name = name;
    • 这是一个复杂的代码。如何向适配器添加更多条目?我正在显示来自带有分页的网络服务器的查询结果。所以我需要能够获得更多结果并添加到当前视图中
    【解决方案3】:

    您需要的是分隔符。使用this guide 找出如何添加分隔符。

    那么在您的Adapter 中,您需要一个变量来告诉您您在字母表中的位置。

    private Char currentChar;
    

    getView-方法中,您需要确定是添加普通项目还是添加分隔符。比如:

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

    要记住的一点是,您可能会与项目的索引混合,因为ListView 会突然包含比数组更多的项目。解决此问题的一种方法是将虚拟项目(可能只是一个空对象)添加到数组中。

    【讨论】:

      【解决方案4】:

      notifyDataSetChanged 会更新列表,是的。

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

      【讨论】:

        【解决方案5】:

        为了使 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();
        }
        

        请注意,有更好的方法来显示这样的分段列表,但这适用于在需要时快速破解。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-15
          • 2020-03-29
          • 1970-01-01
          • 2018-04-18
          • 1970-01-01
          相关资源
          最近更新 更多