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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<EditText
android:id="@+id/editSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="6"
android:ems="10"
android:hint="검색..."
android:inputType="text"
android:textColorHint="#A6A6A6"
android:textSize="24sp" />
<ImageButton
android:id="@+id/imgCancel"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="1"
app:srcCompat="@drawable/baseline_clear_24" />
</LinearLayout>
<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 / 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.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListAdapter;
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;
EditText editSearch;
ImageView imgCancel;
// 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);
editSearch = findViewById(R.id.editSearch);
imgCancel = findViewById(R.id.imgCancel);
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으로 옮김
editSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
String keyword = editSearch.getText().toString().trim();
// 핸들러 만들어서 검색해 달라고 함
DatabaseHandler db = new DatabaseHandler(MainActivity.this, "contact_db", null, 1);
// 리스트 깨끗이 비우고
contactArrayList.clear();
// db에서 검색한 후 받아오기
contactArrayList.addAll(db.searchMemo(keyword));
// 결과를 화면에 보여주기
adapter.notifyDataSetChanged();
// adapter = new ContactAdapter(MainActivity.this, contactArrayList);
// recyclerView.setAdapter(adapter);
}
});
imgCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DatabaseHandler handler = new DatabaseHandler(MainActivity.this, "contact_db", null, 1); // 디비 데러오잠
contactArrayList.clear(); // 방 비워두고
contactArrayList.addAll(handler.getAllContacts()); // 전체 다 받아와
adapter.notifyDataSetChanged(); // 화면도 바꿔주구
editSearch.setText(""); // 검색창 내용도 비우구
}
});
}
@Override
protected void onResume() {
super.onResume();
// 데이터를 먼저 불러오고, contactArrayList에 저장해야 한다.
// DB에서 데이터를 가져온다.
DatabaseHandler handler = new DatabaseHandler(MainActivity.this, "contact_db", null, 1);
// 네트워크는 페이징 처리를 해야 하기 때문에 이런 식으로 추가해야 함.
contactArrayList.clear(); // 비어 있는 상태로 만듦.
contactArrayList.addAll(handler.getAllContacts()); // 가져와서 보여주기 위해 메모리에 저장 // add는 하나 addall은 모두
adapter = new ContactAdapter(MainActivity.this, contactArrayList);
recyclerView.setAdapter(adapter);
}
}
검색 기능을 구현하기 위해 addTextChangedListener 메서드에서 TextWatcher 메서드를 불러왔다.
네트워크 페이징 처리를 위해 리스트들은 clear(); 한 후 데이터를 넣어준다.
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();
}
public ArrayList<Contact> searchMemo(String keyword) {
SQLiteDatabase db = getWritableDatabase();
String query = "select * from contact where name like '%"+keyword+"%' or phone like '%"+keyword+"%'";
Cursor cursor = db.rawQuery(query, null);
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;
}
}
검색을 위해 getAllContacts() 메소드와 같은 형식으로 searchMemo()를 만들어 추가해 준다.