본문 바로가기

프로그래밍/Android

List adapter

 

리스트 관련해 정리한게 하나도 없었다.

희안하게도 근 2년 동안 리스트를 쓸 일도 없었다 -_-;;

물론, BaseAdapter를 상속받아 갤러리 어댑터는 사용했지만

다른 리스트들은 프로젝트에 포함된 적이 없으니..

 

이제서야 리스트와 관련한 어댑터를 정리 해본다.

 

 

ArrayAdapter

string 배열을 위한 어댑터

레이아웃과 하나의 뷰를 표시하기 위한 어댑터이다.

new ArrayAdapter( this, R.layout.xxx, list );

 

커스텀한 레이아웃을 구성하기위해서는

getView() 를 오버라이드해 준다.

getView에서 지정한 레이아웃이 입력되는데, 이 뷰를 inflate 해서 하위 요소들을 얻고,

해당 하위 뷰에 데이터를 설정하면 된다.

 

 

CursorAdapter

일반적으로 db 쿼리에 따른 데이터를 커서로 받아 리스트 항목을 제공하는

용도로 많이 사용된다.

 

뷰를 생성하고, 뷰에 데이터를 연동 시키기 위한 메쏘드를 제공하는데, 이를 오버라이드해 작성해 주어야 한다.

 

newView()

뷰 추가시 어떤 레이아웃을 사용할지를 지정한다.

LayoutInflater 를 사용해 xml 내의 뷰를 가져오게 된다.

 

LayoutInflater inflater = LayoutInflater.from( context );

View v = inflater.inflate( 레이아웃 , parent, false );

 

얻어온 view에서 findViewById를 통해 다시 하위 뷰들을 설정 하고, 리턴해 주면 된다.

 

bindView()

뷰와 커서가 전달되는데, 말그대로 커서의 내용을 뷰에 적용하기 위한 메쏘드 이다.

TextView testView = v.findViewById( ... );

testView.setText(cursor.getString( cursor.getColumnIndex( "키값" )));

 

대강 이런식...

 

 

사용 방식은 Adapter 들과 차이 없다.

CursorAdapter 를 상속받은 어댑터 클래스 구현

pulbic class MyCursorAdapter exteds CursorAdapter

 

액티비티에서 resolver를 가져와 쿼리 후 어댑터 생성

Cursor cursor = this.getContentResolver().query( URI , null, null, null, null );

 

어탭터 생성

MyCursorAdapter mMy = new MyCursorAdapter( this, cursor );

 

리스트에 어댑터 설정

mList.setAdapter( mMy );

 

 

SimpleCursorAdapter( context , 필드 레이아웃, 커서, db 필드 배열, 필드와 대응될 뷰 id )

커서 어댑터의 하위 클래스로 간단한 필드와 뷰를 매칭 시킬때 사용한다.

 

 

SlowAdapter

api demo에 있는 예제로, BaseAdapter 를 기반으로 구현되었다.

리스트를 모두 로딩하지 않고, 스크롤로 항목이 보여질때 로딩되도록 한다. 썸네일이나 웹에서 데이터를 가져와 보여주는 등에 사용될 수 있다.

특별한 내용은 아니고, 스크롤에 따라 플래그 변수를 변경해 해당 플래그에 따라 getView() 동작을 처리해 주면 된다. 

 

리스트 액티비티에서 OnScrollListener를 implements 하고, onScrollStateChanged() 메쏘드를 오버라이드 한다.

OnScrollListener.SCROLL_STATE_TOUCH_SCROLL 상태일때 플래그를 set 한다.

 

adapter의 getView 에서는 해당 플래그가 set 된 경우에는 임시 내용을, 해제된 경우에는 데이터를 채워 넣는다.

 

뷰 홀더의 사용

api demo 중 list 14 는 efficient adapter 예제인데, 여러 뷰를 가진 리스트 아이템에 대한 효율적인 처리에 대해 언급하고 있다.

ViewHolder 라는 구조체를 선언해 사용하는 방법이다.(음.. C 에서는 늘상 하던일인데 -_-;; )

이 구조체를 View의 tag로 등록해 가지고 다니게 된다.

따라서, 매번 inflate와 findViewById를 하지 않아도 되는 장점이 있다.

 

특히, 리스트를 비동기 처리하려고 할때, 리스트 내부 구조를 홀더로 생성해 놓고, 필요에 따라 비 동기적으로 데이터를 설정할 수 있다.

네트워크나 db 등 작업때 AsyncTask 와 함께 많이 사용하는 구조이다.

 

BaseAdapter를 상속받은 adapter 내부에 구조체(클래스)를 선언한다.

static class ViewHolder {

TextView text;

ImageView icon;

}

 

getView 를 작성한다.

public View getView( int position, View convertView, ViewGroup parent ) {

ViewHolder holder;

 

if( convertView == null ) {

요기선 홀더만 생성한다.

CursorAdapter의 newView() 에 해당.

convertView = mInflater.inflate( R.layout.xxx , null );

holder = new ViewHolder();

holder.text = (TextView) convertView.findViewById(R.id.text);

holder.icon = (TextView) convertView.findViewById(R.id.icon);

 

convertView.setTag(holder);

 

} else {

요기서 데이터를 지정한다.

CursorAdapter의 bindView에 해당

holder = (ViewHolder) convertView.getTag();

holder.text.setText( 데이터 );

holder.icon.setImageBitmap( 데이터 );

}

 

return convertView;

}

'프로그래밍 > Android' 카테고리의 다른 글

뷰의 크기 변경,이동  (0) 2011.09.23
리스트뷰 메쏘드 몇개  (0) 2011.09.22
SQLite Database  (0) 2011.09.20
Edittext 관련 사항들  (0) 2011.09.18
MediaStore 오디오 재생목록  (0) 2011.09.17
낙서  (0) 2011.09.07
터치 이벤트 처리순서  (0) 2011.09.01
천천히 로딩되는 리스트 아이템  (0) 2011.08.22
이미지 클리핑 기초  (0) 2011.08.18
ffmpeg 빌드 #3  (0) 2011.07.07