Функция getView () в Listview не работает должным образом при использовании двух различных типов элементов списка - PullRequest
0 голосов
/ 18 июня 2019

У меня есть специальный адаптер Array для ListView, я использую его для контактов, так как я хотел, чтобы просмотр списка был более организованным, я хотел добавить заголовок для первой буквы имени контакта Это мой текущий прогресс:

@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 не имеет заголовка.

Если я продолжаю делать то же самое внезапно, это исправляет себя, и теперь у 1-й позиции снова есть заголовок, прокрутите снова, и теперь это не так, почему это происходит? Есть ли другой метод, который адаптер использует для создания представлений? Пытается ли он предсказать, какой макет он будет использовать для ускорения?

Визуальная справка об ошибке:

Desc

Как вы можете видеть, позиция 0 (для простоты я поместил номер позиции в текстовое представление вместо имени контакта) имеет заголовок в начале и после небольшой прокрутки он просто исчезает, а затем снова появляется .

1 Ответ

0 голосов
/ 27 июня 2019

Когда вы прокручиваете и представления выходят из видимой области, ListView будет повторно использовать те же самые раздутые представления для других местоположений в списке.

Так что если у вас есть логика в вашем методе getView, который можетиногда раздувать R.layout.a, а иногда раздувать R.layout.b, что может привести к неприятностям, потому что тогда вы можете получить convertView, который вам нужно повторно использовать, типа a, но вам нужно представление типа bдля этой конкретной позиции в списке.

Решение состоит в том, чтобы использовать ViewType s, как вы сообщаете ListView, что у вас есть два разных типа макетов, и затем он знает, когда он может перезапустить определенныйвведите и с помощью которого View.

в основном вы должны вернуть переопределение getViewTypeCount() и вернуть 2 (у вас есть два типа раскладок) и переместить логику проверки, нужен ли нам заголовок или нет, на getItemViewType(int position).

См. Здесь: Android ListView с различными макетами для каждой строки

...