티스토리 뷰



이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.
* 알짜배기 프로그램 받기 - http://www.tipssoft.com/bulletin/tb.php/QnA/8406
* 관리자의 Tipssoft 이야기를 들어보세요 ( 트위터 ID : tipssoft )
* 안드로이드 강좌 목록 - http://www.tipssoft.com/bulletin/tb.php/old_bbs/501
이번 강좌에서는 지난번에 다루었던 OnScrollListener 를 이용하여 리스트뷰의 항목 데이터를 동적으로
추가하는 방법에 데이터베이스를 추가적으로 연동하여 사용하는 방법에 대하여 알아보겠습니다.
리스트뷰의 기초적인 부분에 대하여 자세히 알고싶으신 분들은 아래의 강좌를 참고하세요.
리스트뷰 사용하기 - 기초편 : http://www.tipssoft.com/bulletin/tb.php/FAQ/918
리스트뷰 사용하기 - 활용편 : http://www.tipssoft.com/bulletin/tb.php/FAQ/921
안드로이드에서 사용하는 SQLite 데이터베이스에 대하여 잘 모르시는 분은 아래의 강좌를 참고하세요.
지난 강좌를 보고싶으신 분들은 아래의 링크를 참고하세요.
리스트뷰 사용하기 - 동적 항목 추가1 : http://www.tipssoft.com/bulletin/tb.php/FAQ/1188
1. 코드 구성하기
이 예제는 지난 강좌에서 설명한 리스트뷰에 동적으로 항목을 추가하는 방법들 중에서
OnScrollListener 인터페이스의 onScrollStateChanged 메서드를 사용하는 방법을 이용하여
필요할 때마다 데이터베이스에서 데이터를 읽어 리스트뷰에 추가하도록 구성하였습니다.
1.1 데이터베이스 구성
이 예제는 많은 데이터 중에서 필요시마다 일정 개수만큼 리스트뷰에 데이터를 추가하는
것이기때문에 많은 데이터가 추가된 데이터베이스가 필요합니다. 그래서 테이블이 생성될 때
임의로 150 개의 데이터를 추가하도록 구성하였습니다.
예제가 아닌 일반적인 어플리케이션을 구성할 때에는 아래와 같이 데이터베이스를 생성하거나
업데이트 할 때 데이터를 추가하는 등의 긴 작업을 수행하면 문제가 발생할 수 있습니다.
public class MyDBHelper extends SQLiteOpenHelper {
public MyDBHelper(Context context) {
super(context, "memo.db", null, 1);
}
public void onCreate(SQLiteDatabase db) {
// 테이블을 생성하는 SQL 쿼리를 구성한 후 실행하여 테이블을 생성한다.
// 인덱싱을 할 수 있는 _id 컬럼과 실질적인 데이터를 저장하는 content 컬럼을 가진다.
db.execSQL("create table MEMO(_id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT);");

// 예제를 위한 임의의 데이터를 데이터베이스에 추가한다.
String str;
for(int i = 0; i < 150; i++) {
str = "insert into Memo(content) values('MEMO - content " + i + "');";
db.execSQL(str);
}
}

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// ... 생 략 ...
}
}
1.2 데이터베이스 열기
리스트뷰를 사용하는 액티비티에서 데이터베이스에 사용할 수 있도록 1.1 번에서 구성한
MyDBHelper 로 데이터베이스를 열어줍니다.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

String str;
ArrayList<String> str_list = new ArrayList<String>();
m_adapter = new ArrayAdapter(this, R.layout.list_item, str_list);

m_db_helper = new MyDBHelper(this);

// 리스트뷰에 10개의 데이터를 추가한다.
readDatabase();

m_list = (ListView) findViewById(R.id.scroll_list);
m_list.setAdapter(m_adapter);
// 리스트뷰에 OnScrollListener 를 설정한다.
m_list.setOnScrollListener(this);
// 리스트뷰의 하단이 보여지도록 설정한다.
m_list.setSelection(m_list.getCount() - 1);
}
1.3 데이터베이스의 데이터를 리스트뷰에 추가하기
리스트뷰가 만들어진 직 후와 리스트뷰에 데이터가 추가되어야할 시점에서 아래의 메서드를
호출합니다. 데이터베이스에서는 _id 컬럼을 기준으로 데이터를 10개씩 읽어와야하므로
_id 값을 별도로 저장해두어야 합니다.
public int readDatabase()
{
// 읽기용 데이터베이스를 연다.
SQLiteDatabase db = m_db_helper.getReadableDatabase();

String str;
// 처음 데이터를 읽는 경우
if(m_last_db_index == -1) {
// MEMO 테이블의 데이터를 _id 컬럼을 기준으로 오름차순 정렬 후에 _id 와
// content 컬럼을 INSERT_COUNT 개 요청하는 쿼리문을 구성한다.
str = "select _id, content from MEMO order by _id limit " + INSERT_COUNT;
} else {
// MEMO 테이블의 데이터를 _id 컬럼을 기준으로 오름차순 정렬 후에
// m_last_db_index 이상인 _id 와 content 컬럼을 INSERT_COUNT 개 요청하는 쿼리문을
// 구성한다.
str = "select _id, content from MEMO where _id > " + m_last_db_index +
" order by _id limit " + INSERT_COUNT;
}
// 데이터를 검색해주는 쿼리를 구성하여 rawQuery 메소드를 호출한다.
Cursor cursor = db.rawQuery(str, null);

int count = 0;
// 다음 행으로 커서를 이동시킨다.
while(cursor.moveToNext()) {
// 첫번째 컬럼의 데이터를 정수 형식으로 얻는다.
m_last_db_index = cursor.getInt(0);
// 두번째 컬럼의 데이터를 문자열 형식으로 얻는다.
m_adapter.insert(cursor.getString(1), 0);

// 행 수를 센다.
count++;
}

cursor.close();
db.close();
// 추가된 데이터 수를 반환한다.
return count;
}
1.4 리스트뷰의 상단으로 스크롤 됐을 때 항목 추가하기
OnScrollListener 인터페이스중에서 onScrollStateChanged 메서드를 아래와 같이 구현하고,
리스트뷰에 해당 리스너를 설정해줍니다.
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
// 리스트뷰가 구성이 완료되어 보이는 경우
if(view.isShown()){
if(scrollState == SCROLL_STATE_IDLE) {
// 리스트뷰의 0 번 인덱스 항목이 리스트뷰의 상단에 보이고 있는 경우
if(view.getFirstVisiblePosition() == 0) {
// 데이터베이스에서 데이터를 읽은 후 리스트뷰에 추가한다.
int count = readDatabase();

// 0 번 인덱스 항목 위로 count 개의 항목이 추가되었으므로
// 기존의 0 번 인덱스 항목은 count 번 인덱스가 되었다.
// 호출 빈도가 매우 적은 onScrollStateChanged 에서는 기존 0번 항목이 보여져서
// 항목이 추가될때 해당 항목의 모든 영역이 보였을 가능성이 크므로
// 해당 항목을 보이도록 설정한다.
view.setSelection(count);
}
}
}
}

 

댓글