본문 바로가기

안드로이드

리사이클러뷰 리스트에 sqlite 값 뿌려주기

반응형

리사이클러뷰는 재활용 하는 아이템뷰에 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