由於項目的需要,要給用戶顯示一列表單項,讓用戶選擇,之前使用LinerLayout加Button實現,費時費力,而且表現的內容都已經是寫好的內容,對於內容可變的情況下,毫無招架之力。因此在新的項目當中使用了向ListView加入Spinner的方式來表現表單。開發過程中遇到些問題。
一、 遇到的問題:
1、對於Spinner狀態的保持。
2、對Spinner做了相應事件之后,對於ListView的OnItemClick事件的相應的處理。
二、 問題的解決:
第一個問題在於,ListView側重於對數據的表現,而對數據的交互方面是比較差的,因為隨着ListView的上下滾動,其會對內部的數據進行重繪操作,當數據划出屏幕之后將數據移除,同時將划入的數據進行重繪。還有一個問題就是當你點擊Spinner的時候,ListView並不知道你點擊了哪個Spinner。以上兩個原因就造成了,你點擊的Spinner所選擇的項目在屏幕滑來滑去的時候會改變本身的值,同時你無法獲取所選的Spinner的值。
對於這個問題只要加一個Map將Spinner的狀態保持住,讓后在Listview重繪的時候,從這個Map當中取出ListView的值進行賦值操作即可。同時注意,因為ListView並不知道你點擊了哪個Spinner,因此無法通過position作為鍵,這時候,可以首先將能夠以為標識所點擊Item的一個字段作為Spinner的Prompt,當你選中之后,Spinner的Prompt就是你點擊的那個Item,獲取到Prompt作為Map的鍵即可。
對於第二個問題,見我的另一篇博客listView當中有嵌套了有onClickListener的控件時ListView自身的onItemClick無響應的解決方案
三、 具體解決方案見主要代碼:
問題一的主要代碼(ListView的適配器):
package com.yang.adapter; import java.util.HashMap; import java.util.Map; import ouc.sei.R; import android.content.Context; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; import android.widget.Spinner; import android.widget.TextView; public class CheckListAdapter extends BaseAdapter { private Context mContext; private String[] checkListName; // 存儲以名值對。存放Spinner的Prompt和用戶選中的值 private Map<String, Integer> allValues; public CheckListAdapter(Context mContext, String[] checkListName) { this.mContext = mContext; this.checkListName = checkListName; allValues = new HashMap<String, Integer>(); putAllValues(); } private void putAllValues() { for (String str : checkListName) { allValues.put(str, 0); } } public void setAllValues(Map<String, Integer> allValues){ this.allValues = allValues; } @Override public int getCount() { return checkListName.length; } @Override public Object getItem(int position) { return checkListName[position]; } @Override public long getItemId(int position) { return 0; } private class ViewHolder { TextView checkinfo_item_name; Spinner checkinfo_item_value; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = View.inflate(mContext, R.layout.checkinfo_list_item, null); holder = new ViewHolder(); holder.checkinfo_item_name = (TextView) convertView .findViewById(R.id.checkinfo_item_name); holder.checkinfo_item_value = (Spinner) convertView .findViewById(R.id.checkinfo_item_value); // 設置其adapter SpinnerAdapter adapter = new SpinnerAdapter(mContext); holder.checkinfo_item_value.setAdapter(adapter); holder.checkinfo_item_value .setOnItemSelectedListener(new ItemClickSelectListener( holder.checkinfo_item_value)); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } String checkedName = checkListName[position]; holder.checkinfo_item_name.setText(checkedName); //關鍵代碼,配合下面的相應事件使用。 holder.checkinfo_item_value.setPrompt(checkedName); int spinnerOptionPosition = allValues.get(checkedName); Log.d("CheckList", checkedName + " = = " + spinnerOptionPosition); holder.checkinfo_item_value.setSelection(spinnerOptionPosition); return convertView; } private class ItemClickSelectListener implements OnItemSelectedListener { Spinner checkinfo_item_value ; public ItemClickSelectListener(Spinner checkinfo_item_value) { this.checkinfo_item_value = checkinfo_item_value; } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //關鍵代碼 allValues.put(checkinfo_item_value.getPrompt().toString(), position); } @Override public void onNothingSelected(AdapterView<?> arg0) { } } //返回用於選中的所有值 public Map<String,Integer> getSelectValues() { return allValues; } }
問題二的主要代碼:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:descendantFocusability="blocksDescendants" android:orientation="horizontal" > <TextView android:id="@+id/checkinfo_item_name" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentLeft="true" android:layout_gravity="left" android:textColor="@android:color/black" android:textSize="18sp" /> <Spinner android:id="@+id/checkinfo_item_value" style="@style/SpinnerAsEditText" android:layout_width="125dip" android:layout_height="fill_parent" android:layout_alignParentRight="true" /> </RelativeLayout>
四、項目圖片


五、整個項目的下載地址