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? Спасибо.
Ответы
Ответ 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);
}
}