Android SQLlite基本通訊錄(三)
接著就是真正的重點,程式碼
說明一下預期的結構
1.MainActivity放主介面對應程式
2.MyOpenHelper放任何有關SQLlite連結
像是Insert、Update、Delete、Select等,統由此class處理
3.detailFragment放更新及新增介面對應的程式
(由於內容比較多一點,說明皆以註解的方式寫在程式碼中)
說明一下預期的結構
1.MainActivity放主介面對應程式
2.MyOpenHelper放任何有關SQLlite連結
像是Insert、Update、Delete、Select等,統由此class處理
3.detailFragment放更新及新增介面對應的程式
(由於內容比較多一點,說明皆以註解的方式寫在程式碼中)
MainActivity程式碼:
//PlaceholderFragment對應預設的fragment_main.xml檔------------------------- //主介面及對應的程式都寫在這個class裡-------------------------------------- public static class PlaceholderFragment extends Fragment { MyOpenHelper DBHelper; //DBHelper,繫結SQLlite的主程式 ListView list; //主介面的List ArrayListnames = new ArrayList<>(); //放入撈出的名字及電話 ArrayAdapter adapter; //設定ListView適配器 AdapterContextMenuInfo selectedMenuInfo; //長按的選項資訊 public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); DBHelper = new MyOpenHelper(getActivity()); adapter = new ArrayAdapter (getActivity() , android.R.layout.simple_list_item_1 , names); //(context, 格式(可以自製一個view來放),撈出的陣列) list = (ListView) rootView.findViewById(R.id.listView1); list.setAdapter(adapter); list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView arg0, View arg1, int posittion, long id) { //new 出detail,並設定Bundle放入點選的位置 detailFragment detail = new detailFragment(); Bundle bb = new Bundle(); bb.putInt("itemPosittion", posittion); detail.setArguments(bb); //取得目前Activity的FragmentManager FragmentManager fManager= getFragmentManager(); fManager.beginTransaction() //開始轉換 .replace(R.id.container, detail) //將現在container畫面替換為detail .addToBackStack(null) //加入棧,按退回可退到上個畫面 .commit(); //執行 } }); //設定list長按會出現的選單 list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { menu.clear(); menu.add("刪除"); //先清除目前的menu,並新增刪除按鈕 selectedMenuInfo = (AdapterContextMenuInfo) menuInfo; //將長按的選項資訊傳出去 } }); reloadAdapter(); //更新ListView的畫面 return rootView; } //長按選單出現「刪除」對應的事件 @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case 0: //由於刪除按鍵沒設定id,預設為0並逐一增加 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) .setIcon(R.drawable.delete).setTitle("提示") .setMessage(R.string.dialog_message) .setNegativeButton("取消", null) .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { int position = selectedMenuInfo.position; //取得選中的位置 if(position>=0){ DBHelper.delete(position); reloadAdapter(); //刪掉後,要更新畫面 } } }); builder.show(); break; } return super.onContextItemSelected(item); } @Override public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); //如果要在Fragment內新增item,一定要setHasOptionsMenu 為 true super.onCreate(savedInstanceState); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.clear(); menu.add(0 , Menu.FIRST , 0 , R.string.menu_add) .setIcon(R.drawable.add); //新增按鈕(int groupId, int itemId, int order, int titleRes) super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()){ case Menu.FIRST: detailFragment detail= new detailFragment(); Bundle bb = new Bundle(); bb.putInt("add", -1); bb.putInt("itemPosittion", -1); detail.setArguments(bb); //比較特別的是,必預將itemPosittion設為0以下的數 //如果沒設,會預設為0,這樣會抓錯資料跳Error FragmentManager fM = getFragmentManager(); fM.beginTransaction() .replace(R.id.container, detail) .addToBackStack(null) .commit(); break; } return super.onOptionsItemSelected(item); } //更新ListView內容,當資料有變動都必須呼叫這個方法 public void reloadAdapter(){ Cursor c = DBHelper.getAll(); //撈出所有的資料 c.moveToFirst(); //移到第1筆 names.clear(); //清掉之前的紀錄 for(int i = 0 ; i < c.getCount();i++){ names.add(String.format("%s %s",c.getString(1),c.getString(2))); c.moveToNext(); //逐一放入names陣列中 } adapter.notifyDataSetChanged(); //通知Data已經更改,這樣才會更新畫面 } }
MyOpenHelper 程式碼:
public class MyOpenHelper extends SQLiteOpenHelper{ //設定各資料 public static final String DB_NAME="persnal_contacts.db"; public static final int DB_VERSION=1; public static final String TABLE_NAME="contacts"; public static final String ID ="id"; public static final String NAME="name"; public static final String PHONE="phone"; public static final String MOBILE="mobile"; public static final String EMAIL="email"; public static final String POST="post"; public static final String ADDR="addr"; public static final String COMP="comp"; SQLiteDatabase db; Cursor cursor; public MyOpenHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); db = this.getWritableDatabase(); cursor = getAll(); //先選出所有,重要,就算是沒資料也要設 //保險 } //在更新時,可以更改DB_VERSION,這樣就會自動重建資料庫 //DB_VERSION只能往上加,不能往下 //因為這是練習,實際上千萬不要這樣做 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists "+TABLE_NAME); onCreate(db); } @Override public void onCreate(SQLiteDatabase db) { //正常只會執行一次 db.execSQL("create table if not exists "+TABLE_NAME+" (" +ID+" integer primary key," +NAME+" varchar," +PHONE+" varchar," +MOBILE+" varchar," +EMAIL+" varchar," +POST+" varchar," +ADDR+" varchar," +COMP+" varchar)" ); } //取得所有資料 public Cursor getAll(){ return cursor = db.rawQuery("SELECT * FROM "+TABLE_NAME, null); } //新增 public Cursor insert(String name,String phone,String mobile,String email,String post,String addr,String comp){ ContentValues values = new ContentValues(); values.put(NAME, name); values.put(PHONE,phone); values.put(MOBILE, mobile); values.put(EMAIL, email); values.put(POST,post); values.put(ADDR, addr); values.put(COMP,comp); db.insert(TABLE_NAME, null, values); return getAll(); } //取得當前列id public int getId(int position){ cursor.moveToPosition(position); return cursor.getInt(0); } //取得當前列資料 public Cursor getRow(int position){ Log.e("位置",position+""); int id = getId(position); Log.e("id",id+""); String[] columns = {ID,NAME,PHONE,MOBILE,EMAIL,POST,ADDR,COMP}; return cursor = db.query(TABLE_NAME, columns, ID+"=?", new String[]{id+""},null,null,null); } //刪除 public Cursor delete(int position){ int id = getId(position); db.delete(TABLE_NAME, "id=?" , new String[]{""+id}); return getAll(); } //更新 public Cursor update(int id,String name,String phone,String mobile,String email,String post,String addr,String comp){ ContentValues values = new ContentValues(); values.put(NAME, name); values.put(PHONE,phone); values.put(MOBILE, mobile); values.put(EMAIL, email); values.put(POST,post); values.put(ADDR, addr); values.put(COMP,comp); db.update(TABLE_NAME, values, "id=?",new String[]{""+id}); return getAll(); } }
detailFragment 程式碼:
public class detailFragment extends Fragment{ MyOpenHelper DBHelper; EditText[] editTexts; Cursor cursor; int[] etId = {R.id.etName,R.id.etPhone,R.id.etMobile, R.id.etEmail,R.id.etPost,R.id.etAddr,R.id.etComp}; @Override public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); super.onCreate(savedInstanceState); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.clear(); super.onCreateOptionsMenu(menu, inflater); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.detail, container, false); DBHelper = new MyOpenHelper(getActivity()); editTexts = new EditText[etId.length]; ImageButton confrim =(ImageButton) rootView.findViewById(R.id.imageButton1); Bundle bundle = getArguments(); int position = bundle.getInt("itemPosittion"); int add = bundle.getInt("add"); //取得PlaceholderFragment傳來的值 //傳來的是要求更新---------------------------------------------------------------- if(position>=0){ cursor =DBHelper.getRow(position);//取得該列 cursor.moveToFirst(); //移至第一筆 for(int i = 0 ; i < etId.length; i++){ editTexts[i] =(EditText) rootView.findViewById(etId[i]); editTexts[i].setText(cursor.getString(i+1)); confrim.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setIcon(R.drawable.save); builder.setTitle("更新"); builder.setMessage("確定更新此筆連絡人?"); builder.setNegativeButton("取消",null); builder.setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { DBHelper.update(cursor.getInt(0), editTexts[0].getText().toString(), editTexts[1].getText().toString(), editTexts[2].getText().toString(), editTexts[3].getText().toString(), editTexts[4].getText().toString(), editTexts[5].getText().toString(), editTexts[6].getText().toString()); MainActivity.PlaceholderFragment mP = new MainActivity.PlaceholderFragment(); getFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE); //將之前的Fragment清掉 getFragmentManager() .beginTransaction() .replace(R.id.container, mP) .commit(); } }); builder.show(); } }); } } //傳來的是要求新增---------------------------------------------------------------- if(add ==-1){ for(int i = 0 ; i < etId.length; i++){ editTexts[i] =(EditText) rootView.findViewById(etId[i]); } confrim.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setIcon(R.drawable.save); builder.setTitle("新增"); builder.setMessage("確定新增此筆連絡人?"); builder.setNegativeButton("取消",null); builder.setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { DBHelper.insert(editTexts[0].getText().toString(), editTexts[1].getText().toString(), editTexts[2].getText().toString(), editTexts[3].getText().toString(), editTexts[4].getText().toString(), editTexts[5].getText().toString(), editTexts[6].getText().toString()); MainActivity.PlaceholderFragment mP = new MainActivity.PlaceholderFragment(); getFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE); getFragmentManager() .beginTransaction() .replace(R.id.container, mP) .commit(); } }); builder.show(); } }); } return rootView; } }
留言
張貼留言