Android SQLlite基本通訊錄(三)

接著就是真正的重點,程式碼
說明一下預期的結構

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
 ArrayList names = 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;
 }
}


留言

熱門文章