A-B-C-D 와 같은 다양한 데이터가 혼재되어 있는 리스트뷰에서

필요할 때 각 형태의 데이터 별로 필터링 해서 보여주고 싶은 경우가 있습니다.


아래와 같은 경우죠


캡처.PNG


이럴 때 초급자들이 대개 사용하는 방법은 A 라는 데이터만 새로 만들어서 아답터에 새롭게 데이터를 넣는 것입니다.

하지만 이러한 방식이 만약 데이터베이스와 결합되게 되면 빈번한 I/O 를 유발하는 데다가

의도치 않게 많은 객체를 생성하게 되므로 성능상이나 메모리상에 그다지 좋지 않는 모양새를 나타내게 됩니다.

그래서 필요한 것이 바로! Override 를 활용한 아답터에 자체적인 필터링 기능을 붙여 넣는 것입니다.

 

A-B-C-D 가 조합된 리스트를 가지고 있다가 필요할 때에만 전체 리스트에서 A 데이터만 보여주는 방식인거죠

 

아래 예시는

 

남자 - 여자 라는 아이템을 동시 가지고 있을 때 필요시에 남자만 또는 여자만 보여주는 필터 기능을 붙여봤습니다.

거두 절미하고 바로 소스부터 시작하도록 하겠습니다.

(UML 이니 하는건 회사에서 업무상 하는 것만으로도 충분하니 생략 -ㅅ- 하겠습니다)

우선 아답터의 소스입니다.

 package com.nobrain.flteradapter;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class HumanFilterAdapter extends BaseAdapter {
 public final static int ALL = 0;
 public final static int FEMAIL = 1;
 public final static int MAIL = 2;
 
 private int type;
 
 private List<Human> mList;
 private Context mContext;
 
 public HumanFilterAdapter(Context mContext) {
  this.mContext = mContext;
  
  mList = new ArrayList<Human>();
 }

 public void insertHuman(Human item){
  mList.add(item);
 }

 public void remove(int position){
  mList.remove(position);
 }

 @Override
 public int getCount() {
  
  int size = 0;
  
  int fullSize = mList.size();

  //필터 타입별 보여줄 갯수 정의
  switch (type){
  case ALL:
  default:
   size = fullSize;
   break;
   
  case FEMAIL:
  case MAIL:
   
   Human temp;
   for (int i =0; i< fullSize ; i++){
    temp = mList.get(i);
    if(temp.sex == type ){
     size++;
    }
   }
   break;
  }
  
  return size;
 }

 @Override
 public Human getItem(int position) {
  
  Human temp;
  
  int itemIndex = 0;
  int fullSize = mList.size();
  
  //타입별로 가져올 아이템 정의하기
  switch (type){
  case ALL:
   return mList.get(position);
   
  }
  
  for (int i =0; i< fullSize  ; i++){
   temp = mList.get(i);
   if(temp.sex == type ){
    if(position == itemIndex ){
     return temp;
    }
    itemIndex++;
   }
   
  }
  
  return null;
 }

 @Override
 public long getItemId(int position) {
  return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  
  
  TextView tv; 
  if(convertView == null){
   tv= new TextView(mContext);
   
   tv.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, ListView.LayoutParams.WRAP_CONTENT));
   
   tv.setTextSize(20);
   
   convertView = tv;
  }else{
   tv = (TextView) convertView;
  }
  
  // 오버라이드한 메쏘드를 가져옴
  Human item = getItem(position);
  
  if(item != null){
   
   tv.setText(item.name);
  }
  
  return convertView;
 }

 /**
 * 아답터의 타입을 지정한다.
 * @param type 전체/남자/여자 의 값
 */
 public void setType(int type) {
  this.type = type;
 }
}

아답터에 바인딩할 데이터를 정의합니다.

private void initApp() {
  
  mAdapter = new HumanFilterAdapter(MainActivity.this);
  
  Human item;
  
  item = new Human();
  item.sex = HumanFilterAdapter.FEMAIL;
  item.name= "Jessy";
  mAdapter.insertHuman(item);
  
  item = new Human();
  item.sex = HumanFilterAdapter.MAIL;
  item.name= "John";
  mAdapter.insertHuman(item);
  
  item = new Human();
  item.sex = HumanFilterAdapter.FEMAIL;
  item.name= "Fukuyu";
  mAdapter.insertHuman(item);
  
  item = new Human();
  item.sex = HumanFilterAdapter.MAIL;
  item.name= "Jason";
  mAdapter.insertHuman(item);
  
  item = new Human();
  item.sex = HumanFilterAdapter.FEMAIL;
  item.name= "Fukume";
  mAdapter.insertHuman(item);
  
  mListView.setAdapter(mAdapter);

}

저는 별도로 리스트를 관리하지 않고 아답터에 다 위임하는 편이라 위와 같이 소스를 작성하는 편입니다.

클릭 이벤트 발생시 아래와 같이 소스가 구성됩니다.

@Override
public void onClick(View v) {

switch (v.getId()){
case R.id.btn_type_all:
mAdapter.setType(HumanFilterAdapter.ALL);
break;
case R.id.btn_type_female:
mAdapter.setType(HumanFilterAdapter.FEMAIL);
break;
case R.id.btn_type_male:
mAdapter.setType(HumanFilterAdapter.MAIL);
break;
}

mAdapter.notifyDataSetChanged();

}


위와 같이 소스를 소스를 구성하면 아래와 같이 로직이 수행됩니다.

SequenceDiagram1.jpg


그러면 실행된 이미지를 봐야겠죠? ^^

 

Untitled-1.png

그냥 짬내서 한 10분동안 요로코롬 뚝딱 만들어서 자그마한 아답터 사용법 끄적여봤습니다. :)

 

프로젝트 샘플은 첨부파일에 넣었으니 한번 들여다 보시기 바랍니다.

 

그럼..초급자분들 화이팅~^^