리사이클러뷰는 재활용 하는 아이템뷰에 list에 저장된 데이터를 불러온다.
나는 데이터들을 내장 db에 저장하고, 그 저장된 db의 데이터들을 리사이클러뷰의 아이템 뷰에 불러오고싶었다.
그래서 db 에 어떻게 데이터들을 저장하고, 저장되어있는 데이터들을 리사이클러뷰의 리스트에 어떻게 불러올 것인가?
이것이 안드로이드 초보,자바 초보..개발자의 고민이었다..ㅋ.ㅋ
정리한번해볼겸 블로그에 작성해보자..!
--edittext들을 통해 받을 데이터들, Person이라는 클래스 생성
package com.example.myapplication;
public class Person {
String name;
String number;
public Person(String name, String number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
}
-sqliteopenhelper를 상속하여 만든 Persondatabase 클래스
- 테이블생성, 레코드 추가,삭제 ,수정,조회 할 코드를 여기에 작성하면된다
-리사이클러뷰의 리스트에 db테이블에 있는 모든 쿼리를 리스트에 담아 어뎁터의 리스트로 반환하면 된다. (->setitems()함수)
-그래서 어뎁터의 리스트로 반환하려면, Persondatabase 클래스에 public ArrayList<Person>selectAll() 반환함수를만들어놓았다.
-sqlite의 oncreate는 앱 생성시 최초로 한번만 실행된다.그렇기때문에 테이블생성을 여기서 해놓아야한다. 앱 껏다가 키면 db 객체가 open하는 걸로 되어 있는데 oncreate 안거치고 onopend()함수가 실행됨 .
로그찍어보면이롷게..
2021-03-02 16:34:16.634 9456-9456/com.example.myapplication D/PersonDatabase: opening database [person.db].
2021-03-02 16:34:16.642 9456-9456/com.example.myapplication D/PersonDatabase: creating table [PERSON_INFO].
2021-03-02 16:34:16.643 9456-9456/com.example.myapplication D/PersonDatabase: opened database [person.db].
2021-03-02 16:34:16.643 9456-9456/com.example.myapplication D/PersonDatabase: database is open.
2021-03-02 16:35:52.920 9456-9456/com.example.myapplication D/PersonDatabase: opening database [person.db].
2021-03-02 16:35:52.922 9456-9456/com.example.myapplication D/PersonDatabase: opened database [person.db].
2021-03-02 16:35:52.922 9456-9456/com.example.myapplication D/PersonDatabase: database is open.
package com.example.myapplication;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;
public class PersonDatabase {
public static final String TAG="PersonDatabase";
private static PersonDatabase database;
public static String DATABASE_NAME="person.db";
public static String TABLE_PERSON_INFO="PERSON_INFO";
public static int DATABASE_VERSION=1;
private DatabaseHelper dbHelper;
private SQLiteDatabase db;
private Context context;
private PersonDatabase(Context context)
{
this.context= context;
}
public static PersonDatabase getInstance(Context context) { //싱글톤 패턴으로 현재 context를 통해, 현재 앱의 데이터베이스 인스턴스 변수가 한번만 생성되도록 설정
if (database == null)
{
database= new PersonDatabase(context);
}
return database;
}
public boolean open()
{
println("opening database [" + DATABASE_NAME + "].");
dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
return true;
}
public void close() {
println("closing database [" + DATABASE_NAME + "].");
db.close();
database = null;
}
//데이터베이스 쿼리의 결과는 cursor로 반환
public Cursor rawQueary(String SQL)
{
println("\nexecuteQuery called.\n");
Cursor c1 = null;
try {
c1 = db.rawQuery(SQL, null);
println("cursor count : " + c1.getCount());
} catch(Exception ex) {
Log.e(TAG, "Exception in executeQuery", ex);
}
return c1;
}
//데이터베이스 명령문
public boolean execSQL(String SQL) {
println("\nexecute called.\n");
try {
Log.d(TAG, "SQL : " + SQL);
db.execSQL(SQL);
} catch(Exception ex) {
Log.e(TAG, "Exception in executeQuery", ex);
return false;
}
return true;
}
private class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context)
{
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) { //앱이 설치 될때 한번만 실행 됨. getWritableDatabase() 를통해서 접근한것임
println("creating table [" + TABLE_PERSON_INFO + "].");
String DROP_SQL="drop table if exists "+TABLE_PERSON_INFO;
try{
db.execSQL(DROP_SQL);
}catch (Exception ex)
{
Log.e(TAG, "Exception in DROP_SQL", ex);
}
// create table
String CREATE_SQL = "create table " + TABLE_PERSON_INFO + "("
+ " _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
+ " NAME TEXT, "
+ " AUTHOR TEXT, "
+ " CREATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP "
+ ")";
try {
db.execSQL(CREATE_SQL);
} catch(Exception ex) {
Log.e(TAG, "Exception in CREATE_SQL", ex);
}
insertRecord(db, "이름", "사번");
}
public void onOpen(SQLiteDatabase db) { //getWritableDatabase() 를통해서 접근한것이지만,onCreate()접근안하고 onopen을 통하여 db를 연다
println("opened database [" + DATABASE_NAME + "].");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
println("Upgrading database from version " + oldVersion + " to " + newVersion + ".");
if (oldVersion < 2) { // version 1
}
}
private void insertRecord(SQLiteDatabase db, String name, String author) {
try {
db.execSQL( "insert into " + TABLE_PERSON_INFO + "(NAME, AUTHOR) values ('" + name + "', '" + author + "');" );
} catch(Exception ex) {
Log.e(TAG, "Exception in executing insert SQL.", ex);
}
}
}
public void insertRecord(String name, String author) {
try {
db.execSQL( "insert into " + TABLE_PERSON_INFO + "(NAME, AUTHOR) values ('" + name + "', '" + author + "');" );
} catch(Exception ex) {
Log.e(TAG, "Exception in executing insert SQL.", ex);
}
}
public ArrayList<Person>selectAll()
{
ArrayList<Person>result=new ArrayList<Person>();
try {
Cursor cursor = db.rawQuery("select NAME, AUTHOR from " + TABLE_PERSON_INFO, null);
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
String name = cursor.getString(0);
String author = cursor.getString(1);
Person info = new Person(name, author);
result.add(info);
}
} catch(Exception ex) {
Log.e(TAG, "Exception in executing insert SQL.", ex);
}
return result;
}
private void println(String msg) {
Log.d(TAG, msg);
}
}
리스트뷰 어뎁터
-setItems를 통해서 데이터베이스에 담긴 데이터 리스트로 초기화 해준다.
package com.example.myapplication;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.ArrayList;
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder>{
ArrayList<Person> items=new ArrayList<Person>();
public void addItem(Person item)
{
items.add(item);
}
public void setItems(ArrayList<Person> items)
{
this.items=items;
}
public Person getItem(int position)
{
return items.get(position);
}
public void setItem(int position,Person item)
{
items.set(position,item);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
LayoutInflater inflater =LayoutInflater.from(viewGroup.getContext());
View itemView= inflater.inflate(R.layout.person_item,viewGroup,false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewholder, int position) {
Person item=items.get(position);
viewholder.setItem(item);
}
@Override
public int getItemCount() {
return items.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView text_name;
TextView text_number;
public ViewHolder(View itemView)
{
super(itemView);
text_name=itemView.findViewById(R.id.text_name);
text_number=itemView.findViewById(R.id.text_number);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos= getAdapterPosition();
if(pos!=RecyclerView.NO_POSITION)
{
Person p = getItem(pos);
//System.out.println(p.name);
//TODO:다이얼로그 띄우기
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setTitle(p.name);
builder.setMessage("안녕하세요"+p.name+",(사번)"+p.number+"입니다");
builder.show();
}
}
});
}
public void setItem(Person item)
{
text_name.setText(item.getName());
text_number.setText(item.getNumber());
}
}
}
-메인 액티비티에 추가할 인터페이스
package com.example.myapplication;
import java.util.ArrayList;
public interface OnDatabaseCallback {
public void insert(String name, String author);
public ArrayList<Person> selectAll();
}
- 메인액티비티
-추가 버튼을 눌렀을때 edittext에 적은 데이터들이 리사이클러뷰의 리스트에 바로 업그레이드 되도록 구현하였음
- PersonDatabase 객체를 얻어오고 selectAll() 을 통하여 List에 칼럼 값을 담고 배열 형태로 값을 반환, 그 반환된 값을
어뎁터에서 사용되는 setItems에서 매개변수로 받아서 배열값을 바꿔준다.!!!
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements OnDatabaseCallback{
private static final String TAG = "PersonDatabase";
PersonAdapter adapter;
PersonDatabase database;
ArrayList<Person> result;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView= findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager= new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(layoutManager);
EditText edit_name=findViewById(R.id.name);
EditText edit_number=findViewById(R.id.number);
Button button=findViewById(R.id.button);
// open database
if (database != null) {
database.close();
database = null;
}
database = PersonDatabase.getInstance(this);
boolean isOpen = database.open();
if (isOpen) {
Log.d(TAG, " database is open.");
} else {
Log.d(TAG, "database is not open.");
}
adapter=new PersonAdapter();
recyclerView.setAdapter(adapter);
result = selectAll();
adapter.setItems(result);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(edit_name.getText().toString().equals("")||edit_number.getText().toString().equals(""))
Toast.makeText(getApplicationContext(),"데이터를 다시 입력해주세요",Toast.LENGTH_LONG).show();
else {
insert(edit_name.getText().toString(),edit_number.getText().toString());
result = selectAll();
adapter.setItems(result);
adapter.notifyDataSetChanged();
}
}
});
}
@Override
public void insert(String name, String author) {
database.insertRecord(name,author);
Toast.makeText(getApplicationContext(), "정보를 추가했습니다.", Toast.LENGTH_LONG).show();
}
@Override
public ArrayList<Person> selectAll() {
ArrayList<Person> result = database.selectAll();
Toast.makeText(getApplicationContext(), "정보를 조회했습니다.", Toast.LENGTH_LONG).show();
return result;
}
}
'안드로이드' 카테고리의 다른 글
Powermanager (0) | 2021.05.25 |
---|---|
안드로이드 생명주기 (0) | 2021.03.03 |
ConText (0) | 2021.02.05 |
일정시간이후에 실행하기 (0) | 2021.02.03 |
일정시간이후에 실행하기 (0) | 2021.02.03 |