ListView в порядке ArrayAdapter получить путается при прокрутке - PullRequest
41 голосов
/ 02 июня 2010

У меня есть ListView в пользовательском ArrayAdapter, который отображает значок ImageView и TextView в каждой строке. Когда я делаю список достаточно длинным, чтобы вы могли прокручивать его, порядок начинается правильно, но когда я начинаю прокручивать вниз, некоторые из предыдущих записей начинают появляться снова. Если я прокручиваю назад вверх, старый порядок меняется. Выполнение этого многократно в конечном итоге приводит к тому, что весь порядок в списке будет казаться случайным. Поэтому прокрутка списка либо приводит к изменению дочернего порядка, либо рисунок не обновляется правильно.

Что может вызвать что-то подобное? Мне нужно, чтобы элементы отображались пользователю в том же порядке, в котором они добавлены в ArrayList, или по крайней мере, чтобы они оставались в одном статическом порядке. Если мне нужно предоставить более подробную информацию, пожалуйста, дайте мне знать. Любая помощь приветствуется. Спасибо.

Ответы [ 4 ]

57 голосов
/ 06 октября 2010

У меня были похожие проблемы, но при нажатии на элемент в настраиваемом списке элементы на экране последовательно изменялись. Если я нажму еще раз, они вернутся туда, где были изначально.

После прочтения я проверил свой код, где я перегружаю метод getView. Я получал представление из convertView, и если оно было нулевым, тогда я собирал свои вещи. Однако после установки точки останова я обнаружил, что он вызывает этот метод при каждом щелчке и при последующих щелчках, convertView не был нулевым, поэтому элементы не устанавливались.

Вот пример того, что это было:


public View getView(int position, View convertView, ViewGroup parent)
{
    View view = convertView;
    if (view == null)
    {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = vi.inflate(R.layout.listitemrow, null);

        RssItem rssItem = (RssItem) super.getItem(position);
        if (rssItem != null)
        {
            TextView title = (TextView) view.findViewById(R.id.rowtitle);
            if (title != null)
            {
                title.setText(rssItem.getTitle());
            }
        }
    }
    return view;
}

Тонкое изменение перемещает закрывающую скобку для нулевой проверки в представлении сразу после надувания:


public View getView(int position, View convertView, ViewGroup parent)
{
    View view = convertView;
    if (view == null)
    {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = vi.inflate(R.layout.listitemrow, null);
    }
    RssItem rssItem = (RssItem) super.getItem(position);
    if (rssItem != null)
    {
        TextView title = (TextView) view.findViewById(R.id.rowtitle);
        if (title != null)
        {
            title.setText(rssItem.getTitle());
        }
    }
    return view;
}

Надеюсь, это поможет тем, кто испытывает ту же проблему.

4 голосов
/ 10 января 2012

Для дальнейшего разъяснения ответа farcats ниже в более общем виде, вот мое объяснение:

Операция vi.inflate (необходимая здесь для анализа макета строки из XML и создания соответствующего объекта View) заключена в if (view == null) Заявление об эффективности, поэтому раздувание одного и того же объекта не будет происходить снова и снова каждый раз, когда он появляется.

ОДНАКО другие части метода getView используются для установки других параметров и поэтому НЕ должны включаться в оператор if (view == null) .

Аналогично, в другой обычной реализации этого метода некоторые элементы textView, ImageView или ImageButton должны заполняться значениями из списка [position], используя findViewById и после этого .setText или .setImageBitmap операций. Эти операции должны выполняться после того, как и создают представление с нуля с помощью инфляции и , получая существующее представление, если оно не равно нулю.

Еще один хороший пример, где это решение применяется для BaseAdapter, появляется в BaseAdapter, в результате чего ListView выходит из строя при прокрутке

3 голосов
/ 02 июня 2010

ListView повторно использует объекты просмотра при прокрутке. Вы переопределяете метод getView? Вы должны убедиться, что вы установили каждое свойство для каждого представления, не думайте, что оно будет помнить то, что у вас было раньше. Если вы опубликуете этот метод, возможно, кто-то может указать вам на неправильную часть.

0 голосов
/ 03 сентября 2015

У меня есть ListView, AdapterView и View (search_options), который содержит EditText и 3 Spinners. Элементы ListView представляют собой несколько копий макета (search_options), где пользователь может добавить дополнительные параметры в ListView, а затем щелкнуть поиск, чтобы отправить запрос sql, созданный в соответствии с параметрами пользователя.

Я обнаружил, что индексы смешивания convertView добавили в действие глобальный список (myViews), и передал его в ArrayAdapter. Затем в ArrayAdapter (getView) я добавляю в него все вновь добавленные представления (myViews).

Также в getView вместо проверки, если convertView имеет значение null, я проверяю, имеет ли глобальный список (myViews) вид на выбранную (позицию). Это полностью решило проблемы после трехдневного чтения Интернета !!

1- на активность добавить это:

Map<Integer, View> myViews = new HashMap<>();

и затем передайте его в ArrayAdapter с помощью конструктора адаптера.

mSOAdapter = new SearchOptionsAdapter(getActivity(), resultStrs, myViews);

2- на getView:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View view;
    ViewHolder viewHolder;

    if (!myViews.containsKey(position)) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        view = inflater.inflate(R.layout.search_options, parent, false);

        /// ...... YOUR CODE

        myViews.put(position, view);

        FontUtils.setCustomFontsIn(view, getContext().getAssets());

    }else {
        view = myViews.get(position);
    }

    return view;
}

Наконец-то больше нет смешивания предметов ...

...