Подтвердить что ты не робот

ListViews - как использовать функцию ArrayAdapter.addAll() перед API 11?

Я пытаюсь обновить ListView с совершенно новым ArrayList. Для API 11 он отлично работает с использованием метода addAll (...), но он недоступен для более ранних API. Я не могу понять, как обновить весь список, подобный этому, для более старых версий.

ArrayAdapter<String> textList = new ArrayAdapter<String>(listener, R.layout.list_item, stringList);
listener.setListAdapter(textList);

Затем позже...

textList.clear();
textList.addAll(stringList); <--- works fine for Android 3.0 (API Level 11) and beyond, but not before. 

Как вы это делали, прежде чем addAll() был введен в API 11? Спасибо.

4b9b3361

Ответ 1

Простейший способ избежать использования ArrayAdapter.addAll() и ArrayAdapter.add() в цикле, как предположил идиотиггер в своем ответе.

Если вы настаиваете на использовании ArrayAdapter.addAll(), короткий ответ - DIY. Посмотрите источник android.widget.ArrayAdapter здесь, фактическая реализация намного проще, чем вы думали. есть много альтернатив для достижения этого, например:

  • Вариант 1: Внедрите свой собственный массив ArrayAdapter android.widget.BaseAdapter, вы получаете полный контроль над частным экземпляром переменной и методом и может определить, какой метод вы хотите в своем собственной реализации. есть много учебников в Интернете, рассказывающих, как для создания пользовательского адаптера, например здесь и здесь.
  • Вариант 2: Внедрите свой собственный массив ArrayAdapter android.widget.ArrayAdapter, затем добавьте требуемый общедоступный метод addAll() в вашу собственную реализацию ArrayAdapter, у вас нет видимость на частном члене в android.widget.ArrayAdapter поэтому нужна используйте существующий общедоступный API ArrayAdapter.add(), чтобы добавить каждый элемент внутри цикла.

Вариант 1 является предпочтительным и используется очень часто, особенно в ситуации, когда вам нужно визуализировать более сложные пользовательские элементы пользовательского интерфейса в вашем ListView.

Ответ 2

Здесь полный блок кода, который использует собственный addAll() для устройств Android с SDK_INT >= 11, и использует обходной путь для устройств с уровнем API менее 11.

@TargetApi(11)
public void setData(List<String> data) {
    clear();
    if (data != null) {
        //If the platform supports it, use addAll, otherwise add in loop
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            addAll(data);
        } else {
            for(String item: data) {
                add(item);
            }
        }
    }
}

Аннотация @TargetApi(11) используется с ADT 17 для подавления предупреждений Lint, когда у вас есть <uses-sdk android:minSdkVersion="X"/> в AndroidManifest.xml, где X меньше 11. См. http://tools.android.com/recent/lintapicheck для получения дополнительной информации.

Ответ 3

Я сочетал в себе barbeau и Villarey ответы на то, что я считаю хорошим решением:

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setData(List<String> data) {
    clear();
    if (data != null) {
        addAll(data);
    }
}


@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void addAll(String... items) {
    //If the platform supports it, use addAll, otherwise add in loop
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        super.addAll(items);
    }else{
        for(String item: items){
            super.add(item);
        }
    }
}

Ответ 4

Я построил код других людей онлайн, и я создал это. Просто используйте этот класс везде, где это необходимо, вместо класса ArrayAdapter.

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.widget.ArrayAdapter;

import java.util.Collection;
import java.util.List;

public class ArrayAdapterCompat<T> extends ArrayAdapter<T> {
    public ArrayAdapterCompat(Context context, int resource, List<T> entries) {
        super(context, resource, entries);
    }

    /**
     * Add all elements in the collection to the end of the adapter.
     * @param list to add all elements
     */
    @SuppressLint("NewApi")
    public void addAll(Collection<? extends T> list) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            super.addAll(list);
        } else {
            for (T element : list) {
                super.add(element);
            }
        }
    }

    /**
     * Add all elements in the array to the end of the adapter.
     * @param array to add all elements
     */
    @SuppressLint("NewApi")
    public void addAll(T... array) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            super.addAll(array);
        } else {
            for (T element : array) {
                super.add(element);
            }
        }
    }
}

Ответ 5

используя метод textList.add, цикл в списке строк и один за другим, добавленный в текстовый список.

Ответ 6

Вы можете расширить ArrayAdapter на пользовательский класс и реализовать свой собственный метод addAll. Было бы проще использовать ArrayList вместо массива String, поэтому вы можете добавлять данные без восстановления всего набора данных.

Изменить: я помню, что вы можете просто изменить поставляемый массив (или arraylist), который вы загрузили в свой адаптер, а затем вызвать notifyDataSetChanged. Это должно обновить ваш список.

Ответ 7

Я наткнулся на эту тему поздно, но для меня было легко реализовать следующее решение:

public class CustomAdapter extends ArrayAdapter<String>...

public void setData(ArrayList<String> items) {
    clear();
    setNotifyOnChange(false);
    if (items != null) {
        for (String item : items)
            add(item);
    }
    notifyDataSetChanged();
}

Ответ 8

просто вам нужно просто iteration по collection с if statement для version

        //mForecastAdapter.clear();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            mForecastAdapter.addAll(weekForecast);
        }else {
            for (String s : strings) {
                mForecastAdapter.add(s);
            }
        }