모바일 Android ListView 의 Adapter 에 필터링 기능을 붙여보자
페이지 정보
작성자
본문
A-B-C-D 와 같은 다양한 데이터가 혼재되어 있는 리스트뷰에서
필요할 때 각 형태의 데이터 별로 필터링 해서 보여주고 싶은 경우가 있습니다.
아래와 같은 경우죠
이럴 때 초급자들이 대개 사용하는 방법은 A 라는 데이터만 새로 만들어서 아답터에 새롭게 데이터를 넣는 것입니다.
하지만 이러한 방식이 만약 데이터베이스와 결합되게 되면 빈번한 I/O 를 유발하는 데다가
의도치 않게 많은 객체를 생성하게 되므로 성능상이나 메모리상에 그다지 좋지 않는 모양새를 나타내게 됩니다.
그래서 필요한 것이 바로! Override 를 활용한 아답터에 자체적인 필터링 기능을 붙여 넣는 것입니다.
A-B-C-D 가 조합된 리스트를 가지고 있다가 필요할 때에만 전체 리스트에서 A 데이터만 보여주는 방식인거죠
아래 예시는
남자 - 여자 라는 아이템을 동시 가지고 있을 때 필요시에 남자만 또는 여자만 보여주는 필터 기능을 붙여봤습니다.
거두 절미하고 바로 소스부터 시작하도록 하겠습니다.
(UML 이니 하는건 회사에서 업무상 하는 것만으로도 충분하니 생략 -ㅅ- 하겠습니다)
우선 아답터의 소스입니다.
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;
}
}
아답터에 바인딩할 데이터를 정의합니다.
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();
}
위와 같이 소스를 소스를 구성하면 아래와 같이 로직이 수행됩니다.
그러면 실행된 이미지를 봐야겠죠? ^^
댓글목록
등록된 댓글이 없습니다.