본문 바로가기

major/Android

[Android] SQLite 값 listview로 보여주기 - SimpleCursorAdapter 사용법

SQLite로 가져온 데이터를 listview로 출력하는 방법을 정리했습니다.

SimpleCursorAdapter를 사용해서 간단하게 TextView에 출력해보고, CursorAdapter를 커스텀해서 ImageView에 출력하는 방법까지 알려드리겠습니다.

 

1. 기본 사용법

listview.xml 파일을 생성하고, 그냥 TextView만 하나 추가했습니다.

<?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="wrap_content">

    <TextView
        android:id="@+id/listview_txt"
        android:text="Hello Alpaca"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

그리고 activitiy_main.xml 파일에 ListView를 추가합니다.

<?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="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </ListView>

</LinearLayout>

그리고 MainActivity.java에서 아래의 쿼리 문부터 setAdapter까지 코드를 복붙 합니다.

public class MainActivity extends AppCompatActivity {

    DBHelper helper;
    SQLiteDatabase db;

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

        ListView listView =(ListView)findViewById(R.id.listview);

        helper = new DBHelper(MainActivity.this, "newdb.db", null, 1);
        db = helper.getWritableDatabase();
        helper.onCreate(db);

        String sql = "select * from mytable;";
        Cursor c = db.rawQuery(sql, null);
        String[] strs = new String[]{"txt"};
        int[] ints = new int[] {R.id.listview_txt};

        SimpleCursorAdapter adapter = null;
        adapter = new SimpleCursorAdapter(listView.getContext(), R.layout.listview, c, strs, ints,0);

        listView.setAdapter(adapter);

    }
}

실행하면 다음과 같습니다.

실행 화면

db에 들어가 있는 데이터가 listview에 출력된 것을 확인했습니다.

 

2. Adapter를 변형해서 ImageView에 Image 넣기

위의 예제를 사용하면 TextView를 넣는 것은 쉽습니다.

하지만 DB에 저장한 이미지 uri 경로를 불러와서 listview의 ImageView에 넣으려면 조금 더 복잡해집니다.

저는 SimpleCursorAdapter를 상속받아서 새로운 MyCursorAdapter를 만들어서 처리해보겠습니다.

 

먼저 DBHelper에서 TABLE 정보를 수정합니다.

CREATE TABLE if not exists mytable ( _id integer primary key autoincrement, txt text, uri text);

listview.xml 파일을 아래와 같이 수정합니다.

ImageView를 추가했습니다.

<?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="wrap_content">

    <ImageView
        android:id="@+id/listview_img"
        android:layout_width="50dp"
        android:layout_height="50dp"/>

    <TextView
        android:id="@+id/listview_txt"
        android:text="Hello Alpaca"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

MyCursorAdapter.java 파일을 만들고 다음 코드를 복붙 합니다.

public class MyCursorAdapter extends SimpleCursorAdapter {

    private Cursor c;
    private int layout;
    private Context context;
    private String[] from;
    private int[] to;

    public MyCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.c = c;
        this.layout = layout;
        this.context = context;
        this.from = from;
        this.to = to;
    }

    public View getView(int pos, View inView, ViewGroup parent) {
        View v = inView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(layout, null);
        }
        c.moveToPosition(pos);

        String struri = c.getString(c.getColumnIndex(from[0]));
        String txt = c.getString(c.getColumnIndex(from[1]));

        ImageView imageView = (ImageView) v.findViewById(to[0]);
        if (struri != null) { imageView.setImageURI(Uri.parse(struri)); }
        
        TextView textView = (TextView) v.findViewById(to[1]);
        textView.setText(txt);

        return (v);
    }
}

그리고 MainActivity.java를 1의 코드에서 쿼리 이후 부분을 아래와 같이 수정합니다.

String[] strs = new String[]{"uri","txt"};
int[] ints = new int[] {R.id.listview_img, R.id.listview_txt};

MyCursorAdapter adapter = null;
adapter = new MyCursorAdapter(listView.getContext(), R.layout.listview, c, strs, ints);

listView.setAdapter(adapter);

 

그리고 URI로 이미지를 가져오려면 storage 접근 권한이 필요합니다.

Manifest에 아래의 권한을 추가합니다.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

전체 MainActivity.java 코드는 다음과 같습니다.

public class MainActivity extends AppCompatActivity {

    DBHelper helper;
    SQLiteDatabase db;

    String[] permissions = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

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

		// 권한 요청
        ActivityCompat.requestPermissions(MainActivity.this, permissions,  1);

        ListView listView =(ListView)findViewById(R.id.listview);

        helper = new DBHelper(MainActivity.this, "newdb.db", null, 1);
        db = helper.getWritableDatabase();
        helper.onCreate(db);

		// 쿼리
        String sql = "select * from mytable;";
        Cursor c = db.rawQuery(sql, null);
        
        String[] strs = new String[]{"uri","txt"};
        int[] ints = new int[] {R.id.listview_img, R.id.listview_txt};
        
        MyCursorAdapter adapter = null;
        adapter = new MyCursorAdapter(listView.getContext(), R.layout.listview, c, strs, ints);
        listView.setAdapter(adapter);

    }
}

 

실행화면은 다음과 같습니다.

실행 화면

listview에 이미지를 uri로 넣는 과정에서 삽질을 많이 해서 정리해봤습니다.

포스팅에 올바른 방법만 알려드리기 위해 공부를 하는 과정에서 저의 실력도 많이 느는 것 같습니다.

하지만 공부할수록 모르는 게 더 많은 것 같아서 걱정이기도 합니다.

그래도 고민하고 불안해하기보다는 더 열심히 공부하겠습니다 :D


잘못된 내용이 있다면 언제든지 댓글이나 메일로 알려주시면 감사하겠습니다.

이 포스팅이 도움이 되었다면 공감 부탁드립니다.

궁금한 점은 언제든지 댓글 남겨주시면 답변해드리겠습니다:D