由於項目的需要,要給用戶顯示一列表單項,讓用戶選擇,之前使用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>
四、項目圖片
五、整個項目的下載地址
