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
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;
}
}

留言
張貼留言