国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

揭秘在ListView等AdapterView上動態(tài)添加刪除項的陷阱

2019-12-12 06:35:02
字體:
供稿:網(wǎng)友

如何避開在ListView等AdapterView上動態(tài)添加刪除項的陷阱,下面就為大家分享,具體內(nèi)容如下

首先,定義如下array資源,作為列表的加載內(nèi)容:

<resources> <string name="app_name">MyListView</string> <string-array name="language"> <item>Java</item> <item>C</item> <item>C++</item> <item>PHP</item> </string-array>

  然后簡單地寫下布局文件,由于我需要不管列表有多長,始終在底部顯示編輯框和按鈕,所以將ListView中的layout_weight設(shè)為1。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText  android:id="@+id/addLangEdit"  android:layout_width="200px"  android:layout_height="wrap_content" /> <Button   android:id="@+id/addButton"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="添加" /> </LinearLayout></LinearLayout>

  最后添上Activity的代碼,似乎沒什么問題了,運行一下。

public class MyListView extends ListActivity { private ArrayAdapter<CharSequence> mAdapter; private ListView mListView; private EditText mLanguageText; private Button mAddButton;  /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mylist1);  //get the view mListView = getListView(); mLanguageText = (EditText) findViewById(R.id.addLangEdit); mAddButton = (Button) findViewById(R.id.addButton);  //array adapter created from string array resources mAdapter = ArrayAdapter.createFromResource(  this,   R.array.language,   android.R.layout.simple_list_item_1); //set the adapter mListView.setAdapter(mAdapter);  //add listener mAddButton.setOnClickListener(mOnClickListener); }  private OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) {  String text = mLanguageText.getText().toString();  if(null == text || "".equals(text.trim())) {  Toast.makeText(MyListView.this, "輸入不能為空", Toast.LENGTH_SHORT).show();  }else {  mAdapter.add(text);  mAdapter.notifyDataSetChanged();  mLanguageText.setText("");  } } };}


  界面成功顯示,可是每次點擊“添加”,就會拋出java.lang.UnsupportedOperationException,這看似很匪夷所思,因為按照android的api文檔,確實能通過adapter上的add、remove等方法在運行時增刪列表項啊,那問題到底出在哪里呢?

  借助google的幫助,找到如下解答:

  

  這里說到,如果要動態(tài)的改變列表的大小,必須使用一個可變大小的List(如ArrayList),而不能使用固定長度的array,否則將會得到UnsupportedOperationException。也就是說,由于需要從資源文件中加載內(nèi)容,所以我自然就想到調(diào)用ArrayAdapter.createFromResource(Context context, int textArrayResId, int textViewResId)方法來構(gòu)造adapter,而此方法導(dǎo)致ArrayAdapter中維護的是一個定長數(shù)組!對數(shù)組進行add,當(dāng)然就會出錯了。看到這里我不禁感慨,好一個陷阱!!!真相仿佛離我越來越近了,讓我們再進入ArrayAdapter源碼探個究竟。

public class ArrayAdapter<T> extends BaseAdapter implements Filterable {   // 代表ArrayAdapter中的數(shù)據(jù) private List<T> mObjects; // 其他fields  public ArrayAdapter(Context context, int textViewResourceId, List<T> objects) { init(context, textViewResourceId, 0, objects); } public ArrayAdapter(Context context, int textViewResourceId, T[] objects) { // 注意這里的Arrays.asList(...)方法!!! init(context, textViewResourceId, 0, Arrays.asList(objects));  } public static ArrayAdapter<CharSequence> createFromResource(Context context,  int textArrayResId, int textViewResId) { CharSequence[] strings = context.getResources().getTextArray(textArrayResId); return new ArrayAdapter<CharSequence>(context, textViewResId, strings); } private void init(Context context, int resource, int textViewResourceId, List<T> objects) { mContext = context; mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mResource = mDropDownResource = resource; mObjects = objects; mFieldId = textViewResourceId; } public void add(T object) { if (mOriginalValues != null) {  synchronized (mLock) {  mOriginalValues.add(object);  if (mNotifyOnChange) notifyDataSetChanged();  } } else {  mObjects.add(object); // 若該mObjects為固定長度List,此處將拋異常!!!  if (mNotifyOnChange) notifyDataSetChanged(); } } // 其他方法}


  通過源碼可以發(fā)現(xiàn),我上面的思考還是有誤的。ArrayAdapter并沒有單獨維護array類型的數(shù)據(jù),而是統(tǒng)一轉(zhuǎn)換成了List,并存在了mObjects對象中。    

  createFromResource(...)調(diào)用了ArrayAdapter(Context context, int textViewResourceId, T[] objects)構(gòu)造方法,而在該方法的內(nèi)部實現(xiàn)中,android使用Arrays的靜態(tài)方法asList(...)將一個數(shù)組轉(zhuǎn)換為List。熟悉Java的程序員都知道,Arrays.asList(...)方法所返回的并不是一個java.util.ArrayList,而是一個Arrays類的內(nèi)部類,該List實現(xiàn)是不能進行增刪操作的!!(見jdk文檔),對該List進行add將拋出UnsupportedOperationException!

  哈哈,這下終于真相大白了,這樣一來稍微改動一下原來的代碼即可成功運行:D
FInal Solution:

/** *  * @author CodingMyWorld * 2011-7-31 下午04:43:48 */public class MyListView extends ListActivity { private ArrayAdapter<CharSequence> mAdapter; private ListView mListView; private EditText mLanguageText; private Button mAddButton;  /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mylist1);  //get the view mListView = getListView(); mLanguageText = (EditText) findViewById(R.id.addLangEdit); mAddButton = (Button) findViewById(R.id.addButton);  //array adapter created from string array resources List<CharSequence> objects = new ArrayList<CharSequence>(  Arrays.asList(getResources().getTextArray(R.array.language))); mAdapter = new ArrayAdapter<CharSequence>(  this,   android.R.layout.simple_list_item_1,   objects); //set the adapter mListView.setAdapter(mAdapter);  //add listener mAddButton.setOnClickListener(mOnClickListener); }  private OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) {  String text = mLanguageText.getText().toString();  if(null == text || "".equals(text.trim())) {  Toast.makeText(MyListView.this, "輸入不能為空", Toast.LENGTH_SHORT).show();  }else {  mAdapter.add(text);  mAdapter.notifyDataSetChanged(); //not required   mLanguageText.setText("");  } } };}

以上就是關(guān)于Android Listview相關(guān)內(nèi)容介紹,希望對大家的學(xué)習(xí)有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 山丹县| 公主岭市| 宝山区| 枝江市| 雷山县| 罗江县| 洛川县| 襄樊市| 彰化市| 仙游县| 德庆县| 景泰县| 南投市| 海晏县| 赤城县| 佛学| 宜州市| 会理县| 桐梓县| 三河市| 明溪县| 北海市| 海盐县| 敦化市| 兴宁市| 灵川县| 德保县| 双牌县| 错那县| 玉树县| 天津市| 沙湾县| 油尖旺区| 平乐县| 旅游| 梨树县| 开封市| 曲麻莱县| 汾西县| 克东县| 景泰县|