안드로이드 교육을 받고 프로젝트와 함께 사용소스를 블로그에 올릴려고 했는데 늘 그렇듯이 생활하다보니 흐지부지 되어서 그 중 객체바인딩을 상속하여 재수정한 소스를 올린다.
ListView 컨트롤에 객체를 바인딩하는데 사용되는 데이터소스는 객체 리스트와 데이터베이스가 있다.
객체 리스트 바인딩은 ArrayAdapter 객체를 이용하고 데이터베이스 바인딩은 SimpleCursorAdapter 를 사용한다.
이들을 사용하게 되면 다음과 같은 문재점이 있어 이를 재사용할 방법이 있나 싶어 구현해 보아 사용해 보았다.
- 일일히 각각의 뷰에 어댑터를 구현을 해 놓아야 해서 다양한 리스트 뷰페이지 많을 경우, 그에 따라 정의되는 어댑터의 수가 많아져서 불필요한 코드가 생산된다.
- 객체를 바인딩할 경우 ListView 아이템의 여러 뷰에 구현하기 위해서 별도의 어댑터를 구현해야 한다.
먼저 객체목록 소스로 바인딩하는 클래스로 ArrayAdapter 를 재사용하기 위해 모든 객체를 java의 Generics를 사용하여 구현하기로 결정했다.
그리고 객체를 각각의 뷰컨트롤에 바인딩을 하기 위해 리스트를 정의하고 선언하여 각 페이지 뷰에 데이터를 구현하게 했다.
먼저 소스를 보면,
public class MultiBindingAdapter<T> extends ArrayAdapter<T> {
private int _resourceId;
private OnDataItemBindListener<T> _dataItemBindListener;
public MultiBindingAdapter(Context context, int resourceId, List<T> array){
super(context, resourceId, array);
this._resourceId = resourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if( v ==null ){
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(this._resourceId, null);
}
if(_dataItemBindListener != null)
_dataItemBindListener.onItemBind(v, this.getItem(position));
return v;
}
public void setOnDataItemBindListener(OnDataItemBindListener<T> listener){
_dataItemBindListener = listener;
}
}
여기서 바인딩하는 핵심 함수는 getView() 인데 여기에서 ListView의 각 아이템 항목을 바인딩한다.
이를 사용하는 샘플소스는
MultiBindingAdapter<Post> postBindingAdapter =
new MultiBindingAdapter<Post>(this, R.layout.listitemlayout, list);
postBindingAdapter.setOnDataItemBindListener(new OnDataItemBindListener<Post>(){
@Override
public void onItemBind(View v, Post data) {
super.onItemBind(v, data);
TextView tvTitle = (TextView)v.findViewById(R.id.tvListTitle);
if(tvTitle != null)
tvTitle.setText(data.getTitle());
TextView tvSummary = (TextView)v.findViewById(R.id.tvListSummary);
if(tvSummary != null)
tvSummary.setText(data.getSummary());
}
});
setListAdapter(postBindingAdapter);
글 목록을 바인딩하는 샘플인데 List<Post> 객체를 ListView의 각 아이템을 바인딩하여 사용하였다.
다음으로 데이터베이스를 소스로 바인딩하는 클래스로 SimpleCursorAdapter 를 상속하여 구현하였다.
public class MultiBindingCursorAdapter extends SimpleCursorAdapter {
private int _resourceId;
private OnDataItemBindListener<Cursor> _dataItemBindListener;
public MultiBindingCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this._resourceId = layout;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
if( _dataItemBindListener != null){
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(this._resourceId, parent, false);
this._dataItemBindListener.onItemBind(view, cursor);
return view;
}
return super.newView(context, cursor, parent);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
}
public void setOnDataItemBindListener(OnDataItemBindListener<Cursor> listener){
this._dataItemBindListener = listener;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return super.getView(position, convertView, parent);
}
}
여기에서 핵심 메소드는 newView()인데 구현방법은 기존에 구현했던 방법과 유사하다.
이를 사용하는 샘플소스는
this.startManagingCursor(cursor);
MultiBindingCursorAdapter ad =
new MultiBindingCursorAdapter(this, R.layout.documentitemlayout, cursor, new String[] {}, new int[] {});
ad.setOnDataItemBindListener(new OnDataItemBindListener<Cursor>(){
@Override
public void onItemBind(View v, Cursor cursor){
TextView tv = (TextView)v.findViewById(R.id.itemTitle);
if(tv != null)
tv.setText(Util.getStringByCursor(cursor, DocumentDbAdapter.DOCUMENTS_TITLE));
RatingView rating = (RatingView)v.findViewById(R.id.itemRating);
if(rating != null){
rating.setRating(Util.getIntByCursor(cursor, DocumentDbAdapter.DOCUMENTS_IMPORTANT));
rating.setReadable(true);
}
TextView regDate = (TextView)v.findViewById(R.id.itemRegDate);
if(regDate != null)
regDate.setText(Util.getDateByCursor(cursor, DocumentDbAdapter.DOCUMENTS_REGDATE).toLocaleString());
}
});
this.setListAdapter(ad);
이 샘플도 MultiBindingAdapter<T>와 유사해서 특별한 설명을 줄인다.
(퇴근해야 해서...)
아 그리고 마지막으로 리스너를 정의부분이 남았다. 물론 이 리스너도 Generics 를 사용했다.
간단해서 굳이 쓸 필요는 없지만.. 그래도 남긴다.
public void onItemBind(View v, T data){
}
}
'개발관련 > Android' 카테고리의 다른 글
| 안드로이드 웹뷰 오른쪽 스크롤바 공간 없애기 (0) | 2011/04/15 |
|---|---|
| Customized Binding Adapter (3) | 2010/10/27 |
| WebView 웹 브라우저 컴포넌트 사용하기 (0) | 2010/10/06 |
| 사용자 뷰 만들기 - 새로운 뷰 만들기 (0) | 2010/09/05 |
| 사용자 뷰 만들기 - 기존뷰 재정의하기 (0) | 2010/09/03 |
| Intent - 액티비티간 데이터 받기 (0) | 2010/09/01 |



댓글을 달아 주세요
정승현 2011/01/21 11:33 댓글주소 수정/삭제 댓글쓰기
안녕하세요 안드로이드에 대해서 검색을 통해 공부하던 중 여기까지 왔네요
유용한 정보 감사드립니다. 죄송하지만 OnDataItemBindListener란 클래스에 대해서 좀 알수 있을까요?
부탁드립니다
오버라이드 하는 부분을 못 봤네요 죄송 ㅎ
제가 댓글 확인을 이제야 했네요.
제가 자바쪽을 자주 하지 않아서 이상한 점 있으면 많이 알려주세요.
^^