2011. 12. 19. 12:01

안드로이드 리스트뷰(ListVeiw) + 커스텀 어댑터(Custom Adapter)

안드로이드에서 `리스트뷰`위젯은 그냥 단순 기능만을 가지므로 다양하게 활용할 수 있는 유연성이 떨어지는 점이 있죠. 그래서 사용자가 여러가지 데이타를 만들어 리스트로 뷰를 나타내려면 '커스텀 어댑터'를 사용해야 됩니다. 이 커스텀 어댑터를 사용하려면 데이타를 담을 자바 빈(Bean) 파일을 만들어 쓰는게 유용합니다.

간단한 메모 노트앱을 만든다고 가정하고, 여기에 메모의 제목, 메모일시, 메모내용을 저장할 빈 파일을 이렇게 만들어 줍니다.

1. 데이타 빈 Java 파일 (MemoNoteBean.java)

public class MemoNoteBean {
 private int     id ;
 private String memoDateTime ;
 private String title ;
 private String contents ;
 
 public MemoNoteBean() {
  
 }
 
 public MemoNoteBean(int id, String memoDateTime, String title, String contents) {
  this.id = id ;
  this.memoDateTime = memoDateTime ;
  this.title = title ;
  this.contents = contents ;
 }
 
 public int getId() {
  return id ;
 }
 
 public String getMemoDateTime() {
  return memoDateTime ;
 }
 public String getTitle() {
  return title;
 }
 public String getContents() {
  return contents;
 }
 
}

2. 리스트뷰 액티비티에는 customAdapter를 붙입니다. (MemoNoteListActivity.java)

public class MemoNoteListActivity extends Activity { 
 ListView listViewMemo ;
 MemoNoteCustomAdapter customAdapter ;
 MemoNoteBean memoNoteBean = new MemoNoteBean() ;
 ArrayList<MemoNoteBean> arrayList = new ArrayList<MemoNoteBean>() ; 
 
 Button btnCancel, btnTerminate ;
 
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.memolist);
        
        listViewMemo = (ListView)findViewById(R.id.listViewMemo) ;
        btnCancel = (Button)findViewById(R.id.btnCancel) ;
        btnTerminate = (Button)findViewById(R.id.btnTerminate) ;
        
        customAdapter = new MemoNoteCustomAdapter(this, R.layout.custom, arrayList) ; 
        listViewMemo.setAdapter(customAdapter) ;
        
    }
}

3. 리스트뷰에 붙여줄 커스텀 어댑터 액티비티에서는 클래스를 만들때 Super class의 Browse로 들어가 BaseAdapter를 입력하여 상속을 받습니다.

그러면, getCount(), getItem(),getItemId(), getView() 메써드가 자동으로 생성되는데 이들 메써드를 오버라이딩하여 사용하고, 특히 모든 처리는 getView() 메써드 안에서 이루어집니다.

주의할 점은 getView() 메써드 안에서는 파라미터로 따라오는 position 값을 그대로 쓸 수 없어 이걸 final 변수로 한 번 더 재정의해줘야 사용할 수 있습니다. 또한, 이 커스텀 어탭더가 붙게되는 리스트뷰를 여기서는 convertView라고 지칭하고, Activity 역시 context로 바꿔 사용하게 됩니다. 

4. 커스텀 어댑터 액티비티 (MemoNoteCustomAdapter.java)

public class MemoNoteCustomAdapter extends BaseAdapter {
 Context context ;
 LayoutInflater Inflater;
 
 ArrayList<MemoNoteBean> arrayList = new ArrayList<MemoNoteBean>() ;
 
 TextView textViewMemoTitle, textViewMemoDateTime ; 
 
 private int layout ;
 
 public MemoNoteCustomAdapter(Context context, int layout, 
                                             ArrayList<MemoNoteBean> arrayList) {  
  this.context = context ;
  Inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  this.layout = layout;
  this.arrayList = arrayList ; 
 }
 @Override
 public int getCount() {
  // TODO Auto-generated method stub
  return arrayList.size() ;
 }
 @Override
 public Object getItem(int position) {
  // TODO Auto-generated method stub
  return arrayList.get(position).getTitle() ;
 }
 @Override
 public long getItemId(int position) {
  // TODO Auto-generated method stub
  return position ;
 }
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  // TODO Auto-generated method stub
  final int finalPosition = position ;
  if(convertView == null) {
   convertView = Inflater.inflate(layout, parent, false);
  }
  textViewMemoTitle = (TextView)convertView.findViewById(R.id.textViewMemoTitle) ;
  textViewMemoDateTime = (TextView)convertView.findViewById(R.id.textViewMemoDateTime) ;
  textViewMemoTitle.setText(arrayList.get(finalPosition).getTitle() ) ;        
  textViewMemoDateTime.setText(arrayList.get(finalPosition).getMemoDateTime() ) ;        
  return convertView ;
 }
}

단순 메모장 앱이라 메모의 제목과 기록 일시만 커스텀으로 나타냈습니다만, 응용하기에 따라 위젯의 제한 없이 버튼이나, 이미지 버튼도 붙일 수도 있고, 또는 이미지 등으로 다양하게 뷰를 꾸밀 수 있습니다.