1. 程式人生 > >android中adapter.clear()引起的錯誤

android中adapter.clear()引起的錯誤

public class MainActivity extends Activity implements OnClickListener {
	ArrayAdapter<String> adapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		
		setContentView(R.layout.paomadeng);
		Spinner spinner = (Spinner) findViewById(R.id.spinner);
		
		String[] strArray = new String[]{"杭州","上海", "南京", "北京", "廣州", "深圳"};
		
		adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_dropdown_item,  strArray);

		spinner.setAdapter(adapter);
		
		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
					System.out.println(adapter.getItem(position));
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				System.out.println("nothing selected");
			}
		});
		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		adapter.clear();
	}
}

點選這裡的Button,也就是執行onClick()之後,發生如下錯誤:
02-16 13:50:21.062: E/AndroidRuntime(29353): FATAL EXCEPTION: main
02-16 13:50:21.062: E/AndroidRuntime(29353): java.lang.UnsupportedOperationException
02-16 13:50:21.062: E/AndroidRuntime(29353): 	at java.util.AbstractList.remove(AbstractList.java:638)
02-16 13:50:21.062: E/AndroidRuntime(29353): 	at java.util.AbstractList$SimpleListIterator.remove(AbstractList.java:75)
02-16 13:50:21.062: E/AndroidRuntime(29353): 	at java.util.AbstractList.removeRange(AbstractList.java:658)
02-16 13:50:21.062: E/AndroidRuntime(29353): 	at java.util.AbstractList.clear(AbstractList.java:466)
02-16 13:50:21.062: E/AndroidRuntime(29353): 	at android.widget.ArrayAdapter.clear(ArrayAdapter.java:258)

http://stackoverflow.com/questions/10504353/adapter-clear-crashes-android-app

You are probably getting an UnsupportedOperationException, right? This is because the adapters get initialised with an array of objects, which it interally converts to an AbstractList, which cannot be modified.

To solve your problem, you simply need to feed something that implements the List<?>

 interface to the adapter. Example:

含義就是這裡如果使用陣列傳遞到Adapter的話,則它會將這個轉化為AbstractList,而這個AbstractList是不可以修改的。
public ArrayAdapter(Context context, int resource, T[] objects) {
        init(context, resource, 0, Arrays.asList(objects));
    }

可以看到這裡的原始碼是呼叫了Arrays.asList(),我們知道這個Arrays.asList()會返回一個不可修改的ArrayList,而且這個ArrayList是Arrays裡面的。

正確的方式如下:

public class MainActivity extends Activity implements OnClickListener {
	ArrayAdapter<String> adapter;
	
	List<String> datas = new ArrayList<String>();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		
		setContentView(R.layout.paomadeng);
		Spinner spinner = (Spinner) findViewById(R.id.spinner);
		datas.add("杭州");
		datas.add("上海");
		datas.add("南京");
		datas.add("北京");
		datas.add("廣州");
		datas.add("深圳");
		
		adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_dropdown_item,  datas);

		spinner.setAdapter(adapter);
		
		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
					System.out.println(adapter.getItem(position));
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				System.out.println("nothing selected");
			}
		});
		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		datas.clear();
		adapter.notifyDataSetChanged();
	}
}