问题
I'm trying update a ListView with an entirely new ArrayList. For API 11 it works great using the addAll(...) method, but this is not available for earlier APIs. I can't figure out how to go about updating an entire list like this for older versions.
ArrayAdapter<String> textList = new ArrayAdapter<String>(listener, R.layout.list_item, stringList);
listener.setListAdapter(textList);
Then later...
textList.clear();
textList.addAll(stringList); <--- works fine for Android 3.0 (API Level 11) and beyond, but not before.
How did you go about doing this before addAll() was introduced in API 11? Thanks.
回答1:
The simplest way is avoid using ArrayAdapter.addAll() and ArrayAdapter.add() within a loop, like idiottiger suggested in his answer.
If you insist to use ArrayAdapter.addAll(), The short answer is DIY. Check out the source of android.widget.ArrayAdapter here, the actual implementation is much simpler than you thought. there are many alternatives to achieve this, for instance:
- Option 1: Implement you own ArrayAdapter extends android.widget.BaseAdapter, you get full control of private instance variable and method and can define whatever method your want in your own implementation. there are many tutorial on the internet tells how to create custom adapter, like here and here.
- Option 2: Implement you own ArrayAdapter extends android.widget.ArrayAdapter, then add the required public method addAll() to your own ArrayAdapter implementation, you don't have the visibility on private member in android.widget.ArrayAdapter so need use existing public API ArrayAdapter.add() to add every single element within a loop.
Option 1 is preferred and used very commonly, especially in the situation when you need render more complex custom UI stuff within your ListView.
回答2:
Here's the full code block that uses the native addAll() for Android devices with SDK_INT >= 11, and uses the loop workaround for devices with API level less than 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);
}
}
}
}
The @TargetApi(11)
annotation is used with ADT 17 to suppress Lint warnings when you have a <uses-sdk android:minSdkVersion="X"/>
in the AndroidManifest.xml where X is less than 11. See http://tools.android.com/recent/lintapicheck for more info.
回答3:
I combined barbeau and Villarey's answers into what I think is a good solution:
@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:
I built on other peoples code online and I created this. Just use this class wherever needed instead of the ArrayAdapter
class.
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:
using textList.add
method, loop in stringlist, and one by one added to the textList.
回答6:
You can extend ArrayAdapter on a custom class, and implement your own addAll method. It would be simpler if you use an ArrayList instead of String array, so you can add data without rebuilding the whole data set.
Edit: I remembered that you can just modify the supplied array (or arraylist) that you fed into your adapter, and then call notifyDataSetChanged. This should update your list.
回答7:
I came across this thread late, but the following solution was easy to implement for me:
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:
just you need to simple iteration
over the collection
with if statement
for the version
//mForecastAdapter.clear();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mForecastAdapter.addAll(weekForecast);
}else {
for (String s : strings) {
mForecastAdapter.add(s);
}
}
来源:https://stackoverflow.com/questions/9677172/listviews-how-to-use-arrayadapter-addall-function-before-api-11