0

我有一个用于列表视图的自定义数组适配器,我将它用于联系人,因为我希望列表视图更有条理我想为联系人姓名的第一个字母添加标题这是我目前的进展:

@NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItem = convertView;
        LinearLayout header = null;
        String preLabel = " ";
        char firstChar = ' ';
        final Contact c = Contacts.get(position);
        String label = c.name;
        if(position != 0) {//OOb prevention
            preLabel = Contacts.get(position - 1).name;
            firstChar = label.toUpperCase().charAt(0);
        }



        char preFirstChar = preLabel.toUpperCase().charAt(0);
        if (listItem == null) {
            //If its the 1st position or the 1st character of the name is different inflate the layout with a header, else inflate the other layout.
            if(position==0 || firstChar != preFirstChar) {

                listItem = LayoutInflater.from(mContext).inflate(R.layout.contacts_list_item, parent, false);
                header  = (LinearLayout) listItem.findViewById(R.id.section);
                setSection(header, label);
            }else{
                listItem = LayoutInflater.from(mContext).inflate(R.layout.contacts_list2, parent, false);
            }
        }//Etc etc

我认为添加更多代码与此无关,即使在我确定何时放置标题的逻辑错误的情况下,这也有一种奇怪的行为,因为当我向下滚动到视图不存在的点时当我向上滚动位置 0 时可见或已破坏没有标题。

如果我突然继续做同样的事情,它会自行修复,现在第一个位置再次有一个标题,再次滚动,现在它不为什么会发生这种情况?适配器是否有另一种方法用于创建视图?它是否尝试预测它将使用哪种布局来更快?

错误的视觉参考:

描述

如您所见,位置 0(为简单起见,我将位置编号放在 textview 中而不是联系人的姓名中)在开始时有一个标题,在滚动一点后它消失了,然后它重新出现。

4

1 回答 1

1

当您滚动并且视图离开可见区域时,ListView 将为列表中的其他位置重新使用相同的膨胀视图。

因此,如果您的getView方法中的逻辑有时可能会膨胀R.layout.a,有时R.layout.b会导致麻烦,因为那样您可能会得到一个convertView您需要重新使用的类型a,但您需要查看b该特定位置的类型名单。

解决方案是使用ViewTypes,这是你如何告诉 ListView 你有两种不同类型的布局,然后它知道它何时可以回收某个类型以及使用哪个View

基本上你应该返回 overridegetViewTypeCount()和 return 2 (你有两种布局),并将检查我们是否需要标题的逻辑移动到getItemViewType(int position).

请参阅此处:每行具有不同布局的 Android ListView

于 2019-06-27T12:30:15.657 回答