app / res / layout / activity_main.xml

app / res / layout / contact_row.xml

app / res / layout / activity_add.xml

app / res / layout / activity_update.xml

app / java / com.bpdev.contacts / MainActivity.java

app / java / com.bpdev.contacts / adapter / ContactAdapter.java

app / java / com.bpdev.contacts / model / Contact.java

app / java / com.bpdev.contacts / data / DatabaseHandler.java

app / java / com.bpdev.contacts / AddActivity.java

app / java / com.bpdev.contacts / UpdateActivity.java

 

 


 

 

app / res / layout / activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/btnAdd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:padding="10dp"
            android:text="연락처 추가하기"
            android:textSize="24sp" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:background="#3F51B5" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

app / res / layout / contact_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        app:cardBackgroundColor="#D5D6D6">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:orientation="horizontal">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="5"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/txtName"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    android:text="이름"
                    android:textSize="24sp" />

                <TextView
                    android:id="@+id/txtPhone"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"
                    android:layout_marginStart="11dp"
                    android:layout_marginTop="10dp"
                    android:text="전화번호"
                    android:textSize="24sp" />

            </LinearLayout>

            <ImageView
                android:id="@+id/imgDelete"
                android:layout_width="40dp"
                android:layout_height="40dp"
                app:srcCompat="@drawable/baseline_clear_24" />
        </LinearLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

 

 

 

app / res / layout / activity_add.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".AddActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:layout_marginEnd="100dp"
        android:gravity="center|top"
        android:text="연락처 추가"
        android:textSize="34sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/editName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:layout_marginTop="67dp"
        android:layout_marginEnd="100dp"
        android:ems="10"
        android:hint="이름"
        android:inputType="text"
        android:textColorHint="#DDDDDD"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <EditText
        android:id="@+id/editPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="100dp"
        android:ems="10"
        android:hint="전화번호"
        android:inputType="number"
        android:textColorHint="#DDDDDD"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editName" />

    <Button
        android:id="@+id/btnSave"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="150dp"
        android:layout_marginTop="120dp"
        android:layout_marginEnd="150dp"
        android:padding="10dp"
        android:text="저장"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editPhone" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

app / res / layout / activity_update.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".UpdateActivity">

    <Button
        android:id="@+id/btnSave"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="131dp"
        android:layout_marginTop="119dp"
        android:layout_marginEnd="130dp"
        android:padding="10dp"
        android:text="저장"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editPhone" />

    <EditText
        android:id="@+id/editPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="88dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="87dp"
        android:ems="10"
        android:hint="전화번호"
        android:inputType="number"
        android:textColorHint="#DDDDDD"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editName" />

    <EditText
        android:id="@+id/editName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="88dp"
        android:layout_marginTop="67dp"
        android:layout_marginEnd="87dp"
        android:ems="10"
        android:hint="이름"
        android:inputType="text"
        android:textColorHint="#DDDDDD"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:layout_marginEnd="100dp"
        android:gravity="center|top"
        android:text="연락처 수정"
        android:textSize="34sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

 

app / java / com.bpdev.contacts / MainActivity.java

package com.bpdev.contacts;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.bpdev.contacts.adapter.ContactAdapter;
import com.bpdev.contacts.data.DatabaseHandler;
import com.bpdev.contacts.model.Contact;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Button btnAdd;

    // adapter 3개 한세트
    RecyclerView recyclerView;
    ContactAdapter adapter;
    ArrayList<Contact> contactArrayList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnAdd = findViewById(R.id.btnAdd);

        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 새창 띄우기
                Intent intent = new Intent(MainActivity.this, AddActivity.class);
                startActivity(intent);
            }
        });

        // 여기 있던 코드 네 줄 onResume으로 옮김

    }

    @Override
    protected void onResume() {
        super.onResume();
        // 데이터를 먼저 불러오고, contactArrayList에 저장해야 한다.
        // DB에서 데이터를 가져온다.
        DatabaseHandler handler = new DatabaseHandler(MainActivity.this, "contact_db", null, 1);
        contactArrayList = handler.getAllContacts(); // 가져와서 보여주기 위해 메모리에 저장

        adapter = new ContactAdapter(MainActivity.this, contactArrayList);
        recyclerView.setAdapter(adapter);

    }
}

 

 

 

 

 

app / java / com.bpdev.contacts / adapter / ContactAdapter.java

package com.bpdev.contacts.adapter;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bpdev.contacts.R;
import com.bpdev.contacts.UpdateActivity;
import com.bpdev.contacts.data.DatabaseHandler;
import com.bpdev.contacts.model.Contact;

import java.util.ArrayList;

public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ViewHolder> {

    Context context; // alert Dialog
    ArrayList<Contact> contactArrayList; // 메인에서 만들어서 알려줄거임

    public ContactAdapter(Context context, ArrayList<Contact> contactArrayList) {
        this.context = context;
        this.contactArrayList = contactArrayList;
    }

    @NonNull
    @Override
    public ContactAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_row, parent, false);
        return new ContactAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Contact contact = contactArrayList.get(position); // 안드로이드 프레임워크가 일 작동 모듈을 다 만들어 두었어. // 여기 좀 문제인 것 같다 todo
        holder.txtName.setText(contact.name);
        holder.txtPhone.setText(contact.phone);
    }

    @Override
    public int getItemCount() {
        return contactArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        TextView txtName;
        TextView txtPhone;
        ImageView imgDelete;
        CardView cardView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            txtName = itemView.findViewById(R.id.txtName);
            txtPhone = itemView.findViewById(R.id.txtPhone);
            imgDelete = itemView.findViewById(R.id.imgDelete);
            cardView = itemView.findViewById(R.id.cardView);


            imgDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    showAlertDialog();

                }
            });

            cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // UpdateActivity를 실행하는 코드를 여기에 작성
                    Intent intent = new Intent(context, UpdateActivity.class);

                    int index = getAdapterPosition();
                    Contact contact = contactArrayList.get(index);

                    intent.putExtra("contact", contact); // Contact 클래스에 implements Serializable 추가 // 중요 실무 팁

//                    intent.putExtra("id", contact.id);
//                    intent.putExtra("name", contact.name);
//                    intent.putExtra("phone", contact.phone);

                    context.startActivity(intent); // 상속받아서 사용가능한 함수

                }
            });

        }
        private void showAlertDialog() {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("주소록 삭제");
            builder.setMessage("정말 삭제하시겠습니까?");
            builder.setCancelable(false);
            // Yes 버튼 누르면 동작하라~
            builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    // contactArrayList 안에 있는 인덱스에 해당하는 데이터를 사용하면 된다.
                    // 상속받은 함수 이용: 유저가 누른 인덱스를 가져올 수 있는 함수.
                    int index = getAdapterPosition();

                    //  DB에서 삭제해야 완전히 삭제된 거죠
                    DatabaseHandler handler = new DatabaseHandler(context, "contact_db", null, 1); // config 를 만들어서 따로 저장할 예정.

                    Contact contact = contactArrayList.get(index); // 인덱스에 해당하는 id 가져와
                    handler.deleteContact(contact);

                    // 해당 인덱스의 데이터를 삭제한다.
                    contactArrayList.remove(index);
                    // 어댑터에게 화면갱신하라고 알랴줌
                    notifyDataSetChanged();
                    // 화면은 어댑터에게 맡기면 된다.
                }
            });
            builder.setNegativeButton("NO", null);
            builder.show();
        }
    }
}

 

 

 

 

 

app / java / com.bpdev.contacts / model / Contact.java

package com.bpdev.contacts.model;

import java.io.Serializable;

public class Contact implements Serializable {


    public int id;

    public String name;
    public String phone;

    public Contact(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }

    // Overloading
    public Contact(int id, String name, String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }
}

 

 

 

 

 

app / java / com.bpdev.contacts / data / DatabaseHandler.java

package com.bpdev.contacts.data;

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

import androidx.annotation.Nullable;

import com.bpdev.contacts.model.Contact;

import java.util.ArrayList;

public class DatabaseHandler extends SQLiteOpenHelper {

    // extends SQLiteOpenHelper 요구사항 2
    public DatabaseHandler(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    // extends SQLiteOpenHelper 요구사항 1 두 개의 override
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        // 테이블 생성 SQLite 구문 작성
        String query = "create table contact ( id integer primary key autoincrement, name text, phone text);";
        sqLiteDatabase.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        // 기존 테이블 삭제, 새 테이블 만드는 코드 작성

    }

    // 필요한 CRUD 관련 메소드들을 만들어 준다.
    public void addContact(Contact contact){
        SQLiteDatabase db = getWritableDatabase();
        String query = "insert into contact (name, phone) values ( ?, ? )";
        String[] record = { contact.name, contact.phone }; // 배열로 만들어 주었다. // Contact 클래스에 있는 변수들 public으로 설정해 줌.
        db.execSQL(query, record);
        db.close();
    }

    // 저장된 연락처를 모두 가져오는 메소드
    // MainActivity로 먼저 가서 Adapter를 만든다.
    public ArrayList<Contact> getAllContacts(){
        SQLiteDatabase db = getWritableDatabase();
        String query = "select * from contact";
        Cursor cursor = db.rawQuery(query, null);

        // 아래 Contact를 담을 ArrayList 만들자 .
        ArrayList<Contact> contactArrayList = new ArrayList<>();

        if(cursor.moveToFirst()){
            do {
                int id = cursor.getInt(0);
                String name = cursor.getString(1);
                String phone = cursor.getString(2);
                // 여기서의 0,1,2는 컬럼 순서다.

                Contact contact = new Contact(id, name, phone);
                contactArrayList.add(contact);

            } while (cursor.moveToNext());
        } // 만약 받아온 데이터가 있다면 첫번째 데이터부터 실행하라. 매뉴얼에 작성되어 있는 코드

        return contactArrayList;
    }


    public void deleteContact(Contact contact){
        SQLiteDatabase db = getWritableDatabase();
        String query = "delete from contact where id = ?";
        String[] record = { contact.id + "" };
        db.execSQL(query, record);
        db.close();
    }

    public void updateContact(Contact contact){
        SQLiteDatabase db = getWritableDatabase();
        String query = "update contact set name = ?, phone = ? where id = ?";
        String[] record = { contact.name, contact.phone, contact.id+"" };
        db.execSQL(query, record);
        db.close();
    }
}

 

 

 

 

 

app / java / com.bpdev.contacts / AddActivity.java

package com.bpdev.contacts;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.bpdev.contacts.data.DatabaseHandler;
import com.bpdev.contacts.model.Contact;
import com.google.android.material.snackbar.Snackbar;

public class AddActivity extends AppCompatActivity {

    EditText editName;
    EditText editPhone;
    Button btnSave;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);

        editName = findViewById(R.id.editName);
        editPhone = findViewById(R.id.editPhone);
        btnSave = findViewById(R.id.btnSave);

        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name = editName.getText().toString().trim();
                String phone = editPhone.getText().toString().trim();

                if (name.isEmpty() || phone.isEmpty()){
                    Snackbar.make(btnSave, "필수항목을 입력하세요.", Snackbar.LENGTH_SHORT).show();
                    return;
                }

                // 이름 전번 메모리에 저장
                Contact contact = new Contact(name, phone);

                // 이름 전번 DB에 저장
                // DB관련 클래스 만들고 왔다.
                // DB에 저장하는 건 DatabaseHandler가 한다.
                // 1. db handler를 만든다.
                DatabaseHandler handler = new DatabaseHandler(AddActivity.this, "contact_db", null, 1); // 이름들을 정해준다.
                handler.addContact(contact); // db에 저장!

                Toast.makeText(AddActivity.this, "잘 저장되었습니다.", Toast.LENGTH_SHORT).show();
                finish();

            }
        });


    }
}

 

 

 

 

 

app / java / com.bpdev.contacts / UpdateActivity.java

package com.bpdev.contacts;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.bpdev.contacts.data.DatabaseHandler;
import com.bpdev.contacts.model.Contact;
import com.google.android.material.snackbar.Snackbar;

import java.net.CookieHandler;
import java.util.ArrayList;

public class UpdateActivity extends AppCompatActivity {

    EditText editName;
    EditText editPhone;
    Button btnSave;
    Contact contact;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update);

        editName = findViewById(R.id.editName);
        editPhone = findViewById(R.id.editPhone);
        btnSave = findViewById(R.id.btnSave);

        // main에서 선택한 row의 Contact.name과 Contact.phone 셋팅

        contact = (Contact) getIntent().getSerializableExtra("contact"); // data type을 맞춰주도록 한다.

        editName.setText(contact.name);
        editPhone.setText(contact.phone);

        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String name = editName.getText().toString().trim();
                String phone = editPhone.getText().toString().trim();

                if (name.isEmpty() || phone.isEmpty()) {
                    Snackbar.make(btnSave, "필수항목을 입력하세요.", Snackbar.LENGTH_SHORT).show();
                    return;
                }

                contact.name = name;
                contact.phone = phone;

                DatabaseHandler handler = new DatabaseHandler(UpdateActivity.this, "contact_db", null, 1);
                handler.updateContact(contact);

                Toast.makeText(UpdateActivity.this, "잘 저장되었습니다.", Toast.LENGTH_SHORT).show();
                finish();
            }
        });
    }
}

 

 

+ Recent posts