In Hiding

[android] 간단한 주소록(메모) 본문

Tip

[android] 간단한 주소록(메모)

Dohwasa 2010. 11. 18. 11:47
반응형

이미지를 보면 대충 알 수는 있지만 아주 간단한 기능의 주소록이다.

구성은,

- 2개의 Activity : 정보 ListView / 입력창
- 3개의 Class : ListView Class / 입력창 Class / DB생성 Class
- 3개의 Layout xml : main, ListView를 정의하는 row, 입력창을 위한 input

기능은 이미지로도 알 수는 있지만 이미지에 별도 설명을 안 붙일것이라서 글로 쓰면

- 초기화면(ListView)은 DB에 저장된 데이터의 나열 / 다중삭제를 위한 CheckBox가 별도로 붙어있음
- ListView에 표시되는 Data는 성별, 이름, 주소 : 성별은 아이콘으로 표시
- 데이터 추가/삭제는 Menu 키를 눌러 선택할수 있도록
- Menu/추가를 누르면 빈 입력창 Activity가 호출
- 삭제는 CheckBox에서 삭제할 데이터를 선택 후 Menu/삭제를 누르면 처리
- ListView의 항목을 터치하면 터치한 데이터가 입력되어 있는 입력창 Activity를 호출, 수정할수 있도록 한다
- 입력창 Activity는 성별, 이름, 주소, 상세설명으로 구성되고 하단에 저장/취소 버튼을 둔다
- 저장을 누르면 Menu/추가 - 새 데이터 저장, ListView 항목 터치 - modify
- 취소는 다시 ListView로 돌아간다



먼저 xml 파일부터.

1) main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@android:id/list"
  android:layout_width="match_parent"
  android:layout_height="match_parent"></ListView>
  
</LinearLayout>


2) row.xml - ListView의 Layout을 정의

?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/linear"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
<CheckBox
 android:id="@+id/check"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:clickable="false"
 android:focusable="false"
 android:padding="5sp"></CheckBox>
<ImageView
 android:id="@+id/image_sex"
 android:layout_width="40sp"
 android:layout_height="40sp"
 android:padding="5sp"></ImageView>
<TextView
 android:id="@+id/tv_sex"
 android:layout_width="50sp"
 android:layout_height="wrap_content"
 android:padding="5sp"></TextView>
<TextView
 
 android:id="@+id/tv_name"
 android:layout_width="100sp"
 android:layout_height="wrap_content"
 android:padding="5sp"></TextView> 
<TextView
 android:id="@+id/tv_address"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"></TextView>
</LinearLayout>


3) input.xml - 입력창의 Layout을 정의

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">
 <LinearLayout
  android:id="@+id/LinearLayout01"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <TextView
   android:text="성별"
   android:layout_width="80sp"
   android:layout_height="wrap_content"></TextView>

  <EditText
   android:id="@+id/input_sex"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"></EditText>
</LinearLayout>
 <LinearLayout
  android:id="@+id/LinearLayout02"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <TextView
   android:text="이름"
   android:layout_width="80sp"
   android:layout_height="wrap_content"></TextView>
  <EditText
   android:id="@+id/input_name"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"></EditText>
   </LinearLayout>
 <LinearLayout
  android:id="@+id/LinearLayout03"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <TextView
   android:text="주소"
   android:layout_width="80sp"
   android:layout_height="wrap_content"></TextView>
  <EditText
   android:id="@+id/input_address"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"></EditText></LinearLayout>
 <LinearLayout
  android:id="@+id/LinearLayout04"
  android:layout_width="match_parent"
  android:layout_height="220sp"
  android:orientation="vertical">
  <TextView
   android:text="상세내용"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:padding="5sp"></TextView>
  <EditText
   android:id="@+id/input_detail"
   android:layout_width="match_parent"
   android:layout_height="180sp"></EditText>
 </LinearLayout>
 <LinearLayout
  android:id="@+id/LinearLayout05"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <Button
   android:id="@+id/save"
   android:text="저장"
   android:layout_width="165sp"
   android:layout_height="wrap_content"></Button>
  <Button
   android:id="@+id/cancel"
   android:text="취소"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"></Button>
  </LinearLayout>
</LinearLayout>

여기까지가 Layout 설정을 위한 xml 파일 내용이었다.
지금부터는 3개의 Class 파일.

1) Dbclass.class - DB 생성 기능을 하는 Class

package kr.xxx.address;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class Dbclass extends SQLiteOpenHelper {
 
 static final String CREATE_TABLE =
  "create table addressdb (" +
  "_id integer primary key autoincrement, " +
  "sex text not null, " +
  "name text not null, " +
  "address text not null, " +
  "detail text not null);";
 static final String DROP_TABLE =
  "drop table addressdb;"; 
 
 public Dbclass (Context c) {
  super(c, "addressdb.db", null, 1);
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
  // TODO Auto-generated method stub
  db.execSQL(CREATE_TABLE);
 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub
  db.execSQL(DROP_TABLE);
 }

}


2) AddressView.class - ListView를 담당하는 Class

package kr.xxx.address;

import java.util.ArrayList;

import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class AddressView extends ListActivity {
    /** Called when the activity is first created. */
 
 static final String TABLE_NAME = "addressdb";
 SQLiteDatabase db;
 Cursor cursor;
 ListAdapter adapter;
 ArrayList<String> isChecked;
 Intent intent;
 String id;
 
 static final int MENU1_ID=Menu.FIRST;
 static final int MENU2_ID=Menu.FIRST+1;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
               
        intent = new Intent(this, InputWindow.class);
       
    }
   
   
   

 @Override
 protected void onResume() {
  // TODO Auto-generated method stub
  super.onResume();
  
  Dbclass dbclass = new Dbclass(this);
        db = dbclass.getWritableDatabase();
  
  cursor = fetchAllAddress();
  startManagingCursor(cursor);
  adapter = new HelloCursorAdapter(this, cursor);
  setListAdapter(adapter);
  
  cursor.requery();
   
 }

 


 @Override
 protected void onListItemClick(ListView l, View v, int position, long id) {
  // TODO Auto-generated method stub
  super.onListItemClick(l, v, position, id);
  intent = new Intent(getApplicationContext(), InputWindow.class);
  
 /* LinearLayout linear = (LinearLayout)v;
  TextView vId = (TextView)linear.findViewById(R.id.tv_id);
  TextView vSex = (TextView)linear.findViewById(R.id.tv_sex);
  TextView vName = (TextView)linear.findViewById(R.id.tv_name);
  TextView vAddress = (TextView)linear.findViewById(R.id.tv_address);*/
  
  String pId = cursor.getString(0);
  String pSex = cursor.getString(1);
  String pName = cursor.getString(2);
  String pAddress = cursor.getString(3);
  String pDetail = cursor.getString(4);
  
  String[] value = {pId, pSex, pName, pAddress, pDetail};
  intent.putExtra("k", value);
    
  startActivity(intent);
  cursor.requery();
  
 }

 


 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // TODO Auto-generated method stub
  boolean result = super.onCreateOptionsMenu(menu);
  menu.add(0, MENU1_ID, Menu.NONE, "추가");
  menu.add(0, MENU2_ID, Menu.NONE, "삭제");
  
  
  //MenuInflater inflater = new MenuInflater(this);
  
  
  return result;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // TODO Auto-generated method stub
  switch (item.getItemId()) {
  case MENU1_ID:
   String[] value = {null, null, null, "", ""};
   intent.putExtra("k", value);
   startActivity(intent);
   db.close();
   break;
  
  case MENU2_ID:
   for(String id:isChecked)
    deleteAddress(id);
   
   break;
  }
    
  return super.onOptionsItemSelected(item);
 }
 
 
   

 

 

 public void setAddress
  (String id, String sex, String name, String address, String detail) {
     ContentValues values = new ContentValues();
     values.put("sex", sex);
        values.put("name", name);
        values.put("address", address);
        values.put("detail", detail);
     String[] where = {id};
     db.update(TABLE_NAME, values, "_id=?", where);
    }
   
    public void deleteAddress (String id) {
     String[] where = {id};
     db.delete(TABLE_NAME, "_id=?", where);
     cursor.requery();
     
     
    }
   
    public Cursor fetchAllAddress() {
     String[] columns = {"_id", "sex", "name", "address", "detail"};
     Cursor cur =
      db.query(TABLE_NAME, columns, null, null, null, null, "_id DESC");
     return cur;
    }
 
 
   
class HelloCursorAdapter extends CursorAdapter {
 
 public HelloCursorAdapter(Context context, Cursor c) {
  // TODO Auto-generated constructor stub
  super(context, c);
  isChecked = new ArrayList<String>();
  }

 @Override
 public void bindView(View view, Context context, Cursor cursor) {
  // TODO Auto-generated method stub
  String strID = cursor.getString(0);
  //TextView id = (TextView)view.findViewById(R.id.tv_id);
  //id.setText(strID);
  //TextView sex = (TextView)view.findViewById(R.id.tv_sex);
  //sex.setText(cursor.getString(1));
  ImageView sex = (ImageView)view.findViewById(R.id.image_sex);
  String svalue = cursor.getString(1);
  String female = "female";
  String female2 = "여";
  sex.setImageResource(R.drawable.maleicon);
  if(svalue.equals(female)){
   sex.setImageResource(R.drawable.femaleicon);
  }
  if(svalue.equals(female2)){
   sex.setImageResource(R.drawable.femaleicon);
  }
   
    
  
  TextView name = (TextView)view.findViewById(R.id.tv_name);
  name.setText(cursor.getString(2));
  TextView address = (TextView)view.findViewById(R.id.tv_address);
  address.setText(cursor.getString(3));
  
  
  CheckBox check = (CheckBox)view.findViewById(R.id.check);
  check.setTag(strID);
  check.setChecked(isChecked.contains((String)strID));
 
  check.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    CheckBox c = (CheckBox)v;
    if(c.isChecked())
     isChecked.add((String)c.getTag());
    else
     isChecked.remove((String)c.getTag());
   }  
  });
 }

 @Override
 public View newView(Context context, Cursor cursor, ViewGroup parent) {
  // TODO Auto-generated method stub
  LayoutInflater inflater = getLayoutInflater();
  View view = inflater.inflate(R.layout.row, null);
  return view;
  }
 }

 

@Override
protected void onPause() {
 // TODO Auto-generated method stub
 super.onPause();
 db.close();
}
 
 
}


3) InputWindow.class - 입력창 Activity에 해당하는 Class

package kr.xxx.address;


import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;

public class InputWindow extends Activity implements OnClickListener {
 
 static final String TABLE_NAME = "addressdb";
 Intent returnIntent;
 SQLiteDatabase db;
 String _id;
 EditText sex;
 EditText name;
 EditText address;
 EditText detail;
 String[] sID;
 
 //RadioButton males;
 //RadioButton females;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.input);
  
  returnIntent = new Intent (this, AddressView.class);
  sID = getIntent().getStringArrayExtra("k");
       
  Dbclass dbclass = new Dbclass(this);
        db = dbclass.getWritableDatabase();
       
  
  
        sex = (EditText)findViewById(R.id.input_sex);
  name = (EditText)findViewById(R.id.input_name);
  address = (EditText)findViewById(R.id.input_address);
  detail = (EditText)findViewById(R.id.input_detail);
  //males = (RadioButton)findViewById(R.id.male);
  //females = (RadioButton)findViewById(R.id.female);
  
  Button save = (Button)findViewById(R.id.save);
  Button cancel = (Button)findViewById(R.id.cancel);
  
  
  sex.setText(sID[1]);
  name.setText(sID[2]);
  address.setText(sID[3]);
  detail.setText(sID[4]);
  
  
  
  save.setOnClickListener(this);
  cancel.setOnClickListener(this);
     
 }
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  
  if(v.getId()== R.id.save){
   if(sID[0]==null) {
      
   addAddress(sex.getText().toString(), name.getText().toString(),
     address.getText().toString(), detail.getText().toString());
   
   
   } 
   else{
    setAddress(sID[0], sex.getText().toString(), name.getText().toString(),
      address.getText().toString(), detail.getText().toString());
   }
   startActivity(returnIntent);
   
  }else if(v.getId()==R.id.cancel){
   /*sex.setText("");
   name.setText("");
   address.setText("");
   detail.setText("");*/ // case1)입력창 공백처리용
   
   startActivity(returnIntent); //case2)ListActivity 호출용
  }
 }//Onclick 끝

 public String addAddress
 (String sex, String name, String address, String detail) {
    ContentValues values = new ContentValues();
     values.put("sex", sex);
     values.put("name", name);
     values.put("address", address);
     values.put("detail", detail);
  
     Long id = db.insert(TABLE_NAME, null, values);
     return id.toString();
 }
 
 public void setAddress
  (String id, String sex, String name, String address, String detail) {
  ContentValues values = new ContentValues();
  values.put("sex", sex);
  values.put("name", name);
  values.put("address", address);
  values.put("detail", detail);
  String[] where = {id};
  db.update(TABLE_NAME, values, "_id=?", where);
}
 @Override
 protected void onPause() {
  // TODO Auto-generated method stub
  super.onPause();
  db.close();
 }
 
}
 

- 각각의 코드에 대응하는 설명은 생각나면 쓰겠다.
- Activity는 Intent를 써서 호출했고, 추가 기능시의 Data 전송은 Intent에 배열로 Data를 넣고
  getStringArrayExtra를 써서 끄집어냈다. Parcelable이나 직렬화 객체를 써서 Bundle로 넘기는게
  더 깔끔하긴 하다는데 100% 이해 못하는 코드는 어거지로 쓰지 않는 주의라서 일단 이렇게 처리.
- 꽤 조잡한 코딩이지만 혹시 이거라도 필요한 사람이 있을까봐 올려본다.


반응형
Comments