2012-03-13 52 views
17

我正在嘗試用一個全新的ArrayList更新一個ListView。對於API 11,它使用addAll(...)方法效果很好,但這不適用於較早的API。我無法弄清楚如何更新舊版本的整個列表。ListViews - 如何在API 11之前使用ArrayAdapter.addAll()函數?

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中引入?謝謝。

回答

11

最簡單的方法是避免在循環內使用ArrayAdapter.addAll()和ArrayAdapter.add(),就像在他的答案中提出的idiottiger一樣。

如果你堅持使用ArrayAdapter.addAll(),簡短的答案是DIY。查看android.widget.ArrayAdapter here的源代碼,實際的實現比您想象的要簡單得多。有很多的替代品來實現這一點,例如:

  • 選項1:實現你自己的ArrayAdapter延伸 android.widget.BaseAdapter,你私有的實例 變量和方法的完全控制,可以定義任何方法你想在你的 自己的實現。互聯網上有很多教程告訴我們如何創建自定義適配器 ,如herehere
  • 選項2:實現你自己的ArrayAdapter延伸 android.widget.ArrayAdapter,然後添加所需的公共方法 中的addAll(),以自己的ArrayAdapter的實現,你不必在android.widget私有成員在 知名度。 ArrayAdapter因此需要 使用現有的公共API ArrayAdapter.add()在循環內添加每個單獨的 元素。

選項1是首選,並且非常常用,特別是在需要在ListView中呈現更復雜的自定義UI內容時。

+1

不會是矯枉過正實現從BaseAdapter他ArrayAdapter的自己的版本只是有一個方法的addAll?從ArrayAdapter構建它應該足夠了。 – josephus 2012-03-13 03:19:42

+0

是的,仍然值得查看源代碼以瞭解適配器是如何實現的。 – yorkw 2012-03-13 03:24:35

+3

這有點不相關,但如果您使用Eclipse來開發Android應用程序,請查看此帖:http://www.helloandroid.com/content/gold-android-developers-add-aosp-source-code-eclipse- android-sources-plugin – josephus 2012-03-13 03:39:01

1

使用textList.add方法,在stringlist中循環,並逐個添加到textList中。

1

您可以在自定義類上擴展ArrayAdapter,並實現自己的addAll方法。如果使用ArrayList而不是String數組,那將會更簡單,因此您可以添加數據而無需重新構建整個數據集。

編輯:我記得你可以修改提供給你的適配器的數組(或arraylist),然後調用notifyDataSetChanged。這應該更新你的列表。

+0

所以你的意思是在這種情況下,我只是改變變量'stringList'的值,然後調用'textList.notifyDataSetChanged();'?我實際上已經嘗試過,但沒有奏效。我錯過了什麼嗎?我想我在其他地方讀過,如果你編輯適配器'.add'或'.clear'或'.remove',這種方法纔有效。 – mattboy 2012-03-13 07:06:50

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(); 
} 
19

下面是一個使用本機中的addAll()與SDK_INT> = 11的Android設備的完整的代碼塊,並使用循環的解決方法與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警告,當你在AndroidManifest.xml中<uses-sdk android:minSdkVersion="X"/>其中X是小於11。有關更多信息,請參閱http://tools.android.com/recent/lintapicheck

+0

好的答案,但讓我分享一下我的經驗:如果你使用多於x個元素的「add」方法(我最終設置爲100),因爲在每個「add」方法之後,會有一個「 notifydatasetchanged「打電話,會有一個崩潰! – Analizer 2014-09-10 12:11:27

+0

@Analizer有很多記錄,也許你最好使用'CursorAdapter'?請參閱http://stackoverflow.com/questions/21130162/better-to-use-cursor-adapter-or-array-adapter。 – 2014-09-10 14:28:27

+0

這不是一個壞主意,但我沒有使用數據庫,記錄是從服務器的JSON響應中獲取的。 – Analizer 2014-09-11 08:38:25

4

我結合巴比亞烏和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); 
     } 
    } 
} 
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); 
      } 
     } 
    } 
} 
0

只需要簡單的iterationcollectionif statementversion

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