標籤:listview checkbox android preferences 資訊儲存
最近做一個項目時想要增加安卓端的一個功能,就是增加一個activity上面有很多checkbox的勾選資訊,然後可以給人選擇多選框,看起來還算很簡單。。但是真正做起來就有很多麻煩了。。
雖然我對安卓有點瞭解,以前也看過一些代碼,但都是看別人的代碼,看代碼當然簡單啦,這下要全部自己寫,這下有點棘手了,一開始真是無從下手啊,後來去網上查了一下,覺得有個人的寫法不錯,就是用listview匯入adapter的布局這樣子,於是我就照著他的代碼的原型開始改了起來。
改了N久,終於改的有點樣子了,其中也花了很多精力呢!!所以趁熱先記錄下來,免得以後忘了,忘了再寫的話那可是事倍工半呢!
我新添加的代碼有四個檔案,分別是Adapter.java,ListViewDemo,java,choice.xml,problem_item.xml這四個檔案。
遇到的問題及解決方案:
1.建立的多選框選定以後跳轉到別的介面後再次點入這個介面後以前的多選框資訊不能儲存,這樣選擇的資訊就不能記錄下來了。
解決方案:應用preference進行儲存,將多選框選擇資訊寫進了preference後下一次再次進入這個介面後就讀取初始化資訊來進行讀取以前的記錄資訊。從而將多選框的記錄勾上。
2.preference只能以鍵值對來儲存,當這個activity有多個其他的資訊框調用時,就會產生不能記錄所有的多選框選擇資訊,舉個例子,就好像有100個學生,你要為每個學生的類別進行多選框操作,比如說選擇上課科目之類的,科目的哪個activity是一樣的,但是資料不一樣,這樣你就需要儲存多選框資料了,儲存一個還好,但要儲存每一個人的資訊的話就需要動一番腦筋了。
解決方案:將每一個學生的ID發送到選擇框activity,每次開啟時讀取對應學生ID對於的鍵值,因為多選框,所以有多個值,為了方便我就將全部的多選框轉換為01字串,0代表沒有選中,1代表選中。然後再解析出是否被選中就可以了。
下面是相應功能代碼,只供借鑒,不足望指出:
Adapter.java
public class Adapter extends BaseAdapter{private ArrayList<String> list;//填充資料的listprivate static HashMap<Integer,Boolean> isSelected;//用來控制checkBox的選中情況private Context context;//上下文private LayoutInflater inflater=null;//用來匯入布局public Adapter(ArrayList<String> list,Context context)//構造器{this.context = context;this.list = list;inflater = LayoutInflater.from(context); isSelected = new HashMap<Integer, Boolean>(); initDate();//初始化資料 }//初始化選擇判斷為falseprivate void initDate(){for(int i=0;i<list.size();i++){isSelected.put(i, false);}}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn list.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder = null;if(convertView==null){holder = new ViewHolder(); convertView=inflater.inflate(R.layout.problem_item,null);//匯入布局並且賦給convertviewholder.tv =(TextView)convertView.findViewById(R.id.item_tv);//故障資訊holder.cb =(CheckBox)convertView.findViewById(R.id.item_cb);//勾選框convertView.setTag(holder);}else{holder = (ViewHolder) convertView.getTag(); }// 設定list中TextView的顯示 holder.tv.setText(list.get(position)); // 根據isSelected來設定checkbox的選中狀況 holder.cb.setChecked(getIsSelected().get(position)); return convertView; }public static HashMap<Integer,Boolean> getIsSelected() { return isSelected; } public static void setIsSelected(HashMap<Integer,Boolean> isSelected) { Adapter.isSelected = isSelected; }
ListViewDemo.java
public class ListViewDemo extends Activity {private ListView lv; private Adapter mAdapter; private ArrayList<String> list; private Button bt_selectall; private Button bt_cancel; private Button bt_deselectall; private Button bt_yes; private int checkNum; // 記錄選中的條目數量 private TextView tv_show;// 用於顯示選中的條目數量 private int id;//訊息編號,用來儲存故障標號,從上一個介面傳來 private String defaul="";//預設的全部不勾選 private String selectall="";//全部勾選 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.choice); Intent i=getIntent();Bundle b=i.getBundleExtra("ID");id=b.getInt("id"); /* 執行個體化各個控制項 */ lv = (ListView)findViewById(R.id.list); bt_selectall = (Button) findViewById(R.id.bt_selectall); bt_cancel = (Button) findViewById(R.id.bt_cancelselectall); bt_deselectall = (Button) findViewById(R.id.bt_deselectall); bt_yes=(Button) findViewById(R.id.ok); tv_show = (TextView) findViewById(R.id.tv); list = new ArrayList<String>(); initDate(); //初始化勾選框資訊,預設都是以未勾選為單位 for(int n=0;n<list.size();n++) { defaul =defaul +"0"; selectall= selectall +"1"; } // 為Adapter準備資料 // 執行個體化自訂的MyAdapter mAdapter = new Adapter(list, this); // 綁定Adapter lv.setAdapter(mAdapter); getCheck();//擷取資訊,也可說是初始化資訊 // // 全選按鈕的回調介面 bt_selectall.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 遍曆list的長度,將MyAdapter中的map值全部設為true for (int i = 0; i < list.size(); i++) { Adapter.getIsSelected().put(i, true); } // 數量設為list的長度 checkNum = list.size(); // 重新整理listview和TextView的顯示 dataChanged(); } }); // 取消按鈕的回調介面 bt_cancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 遍曆list的長度,將已選的按鈕設為未選 for (int i = 0; i < list.size(); i++) { if (Adapter.getIsSelected().get(i)) { Adapter.getIsSelected().put(i, false); checkNum--;// 數量減1 } } // 重新整理listview和TextView的顯示 //dataChanged(); } }); // 反選按鈕的回調介面 bt_deselectall.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 遍曆list的長度,將已選的設為未選,未選的設為已選 for (int i = 0; i < list.size(); i++) { if (Adapter.getIsSelected().get(i)) { Adapter.getIsSelected().put(i, false); checkNum--; } else { Adapter.getIsSelected().put(i, true); checkNum++; } } // 重新整理listview和TextView的顯示 //dataChanged(); } }); //確定返回的按鈕 bt_yes.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String str="";//確定後直接將資訊寫入preference儲存以備下一次讀取使用 for(int i=0;i<list.size();i++) { if(Adapter.getIsSelected().get(i)) { str= str+'1'; } else { str = str+'0'; } } saveCheck(String.valueOf(id),str);//將資料已字串形式儲存起來,下次讀取再用 finish(); } }); //綁定listView的監聽器 lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // 取得ViewHolder對象,這樣就省去了通過層層的findViewById去執行個體化我們需要的cb執行個體的步驟 ViewHolder holder = (ViewHolder) arg1.getTag(); // 改變CheckBox的狀態 holder.cb.toggle(); // 將CheckBox的選中狀況記錄下來 Adapter.getIsSelected().put(arg2, holder.cb.isChecked()); // // 調整選定條目 if (holder.cb.isChecked() == true) { checkNum++; } else { checkNum--; } // 用TextView顯示 //tv_show.setText("已選中"+checkNum+"項"); } }); } //得到儲存在這個activity中的資料 public void getCheck() { SharedPreferences mPerferences=PreferenceManager.getDefaultSharedPreferences(this);//擷取預設的preference //擷取activity私人的preference SharedPreferences m_private=this.getPreferences(MODE_PRIVATE); String counter=mPerferences.getString(String.valueOf(id), defaul);//如果沒有擷取到的話預設是0 for(int i=0;i<list.size();i++) { if(counter.charAt(i)=='1') { Adapter.getIsSelected().put(i, true); } } } //儲存需要儲存的資料 public void saveCheck(String ID,String data) { //儲存shuju SharedPreferences mPerferences=PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences m_private=this.getPreferences(MODE_PRIVATE); SharedPreferences.Editor mEditor=mPerferences.edit(); mEditor.putString(ID, data); mEditor.commit(); } // 初始化資料 private void initDate() { for (int i = 0; i < 15; i++) { list.add("data" + " " + i); } } // 重新整理listview和TextView的顯示 private void dataChanged() { // 通知listView重新整理 mAdapter.notifyDataSetChanged(); // TextView顯示最新的選中數目 //tv_show.setText("已選中" + checkNum + "項"); //這個功能還不完善,儲存後再開啟沒把這個儲存進去,會算錯。 }
choic.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="400dp" /> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/bt_selectall" android:gravity="center" /> <Button android:id="@+id/bt_selectall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/list" android:layout_gravity="bottom" android:text="全選" /> <Button android:id="@+id/bt_cancelselectall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/bt_selectall" android:layout_below="@+id/list" android:text="取消選擇" /> <Button android:id="@+id/bt_deselectall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/list" android:layout_toRightOf="@+id/bt_cancelselectall" android:text="反選" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/list" android:layout_toRightOf="@+id/bt_deselectall" android:text="確定" /> </RelativeLayout>
problem_item.xml
<?xml version="1.0" encoding="UTF-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <TextView android:id="@+id/item_tv" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" /> <CheckBox android:id="@+id/item_cb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:focusable="false" android:focusableInTouchMode="false" android:gravity="center_vertical" /></LinearLayout>
ViewHolder.java
public class ViewHolder { public TextView tv = null; public CheckBox cb = null; }
下面是選項的