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

17

Я пытаюсь обновить 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? Спасибо.

    
задан mattboy 13.03.2012 в 02:29
источник

8 ответов

11

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

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

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

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

    
ответ дан yorkw 13.03.2012 в 03:48
источник
19

Вот полный блок кода, который использует собственный addAll () для Android-устройств с SDK_INT & gt; = 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. См. Ссылка для получения дополнительной информации.

    
ответ дан Sean Barbeau 07.09.2012 в 16:48
источник
4

Я сочетал ответы 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);
        }
    }
}
    
ответ дан elBradford 13.12.2012 в 01:43
источник
3

Я построил код других людей онлайн, и я создал это. Просто используйте этот класс везде, где это необходимо, вместо класса 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);
            }
        }
    }
}
    
ответ дан KVISH 15.12.2013 в 07:04
источник
1

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

    
ответ дан idiottiger 13.03.2012 в 02:48
источник
1

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

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

    
ответ дан josephus 13.03.2012 в 04:13
источник
0

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

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();
}
    
ответ дан elprl 06.09.2012 в 16:08
источник
0

просто вам нужно просто 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);
            }
        }
    
ответ дан Basheer AL-MOMANI 07.01.2016 в 22:03
источник