프로그래밍/Android

안드로이드 EditText를 이용해 리스트뷰 검색 기능 만들기

Lou Park 2016. 7. 7. 12:45

오늘은 EditText를 이용해 검색되는 리스트뷰를 만들어 보겠다.

다음 GIF처럼 작동되는 것이고, 리스트뷰 아이템의 이름에 따라 검색이된다.

나는 이번에 게임에나오는 포션들을 검색할 수 있는 것으로 예제를 만들어 보겠다.



준비물은 만들어진 ListView, ListView Item Layout, ListViewAdapter

그리고 검색할 Activity다.


ListView와 ListView Item Layout,  그리고 ListViewAdpater를 만드는 방법과

동작하는 방식은 다른 강의에서 보시고! ㅎㅎ

이 강의에서는 검색기능 구현에만 초점을 맞출 예정이다.


먼저 내 PotionListViewAdapter부터 보겠다.

PotionListViewAdapter.java

package com.lx5475.****;


/**
* Created by gold24park on 2016. 7. 7..
*/
public class PotionListViewAdapter extends BaseAdapter {

// Declare Variables
Context context;
LayoutInflater inflater;
private List<Potion> potionList = null;
private ArrayList<Potion> arrayList;
public PotionListViewAdapter(Context context, List<Potion> potionList) {
this.context = context;
this.potionList = potionList;
inflater = LayoutInflater.from(context);
this.arrayList = new ArrayList<Potion>();
this.arrayList.addAll(potionList);
}

public class ViewHolder {
TextView tv_name;
ImageView iv_icon;
}

@Override
public int getCount() {
return potionList.size();
}

@Override
public Potion getItem(int position) {
return potionList.get(position);
}

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

@Override
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
final Potion potion = potionList.get(position);


if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.item_listview, null);
// Locate the TextViews in listview_item.xml
holder.tv_name = (TextView) view.findViewById(R.id.tv_name);
holder.iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.tv_name.setText(potion.name);
Glide.with(context).load(potion.icon).into(holder.iv_icon);

// Listen for ListView Item Click
view.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
Intent intent = new Intent(context, BrewingActivity.class);;
...
context.startActivity(intent);
}
});

return view;
}

// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
potionList.clear();
if (charText.length() == 0) {
potionList.addAll(arrayList);
} else {
for (Potion potion : arrayList) {
String name = context.getResources().getString(potion.name);
if (name.toLowerCase().contains(charText)) {
potionList.add(potion);
}
}
}
notifyDataSetChanged();
}

}

여기서 중요한 부분은 List<> potionList, ArrayList<> arrayList와 filter 메소드이다.

potionList는 검색 후 나오는 아이템들을 담은 리스트다.

arrayList는 이 어댑터가 생성될때 검색가능한 아이템들을 모두 가지고 있는다. (생성자 부분)

그러다가 filter 메소드에 의해 EditText에 입력된 이름이 걸러지면서 potionList에 해당되는 아이템들이 추가되고,

notifyDataSetChanged() 가되면서 자동으로 리스트뷰가 갱신된다.


다음은 EditText가 있는 Activity를 보겠다.

PotionSearchActivity.java

public class PotionSearchActivity extends AdlibActivity {

private PotionListViewAdapter adapter;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_search);
init();

//검색창
editsearch.addTextChangedListener(new TextWatcher() {

@Override
public void afterTextChanged(Editable arg0) {

String text = editsearch.getText().toString()

.toLowerCase(Locale.getDefault());
adapter.filter(text);
}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
}

public void init() {
ButterKnife.bind(this);
this.setAdlibKey(MainActivity.ADLIB_API_KEY);
this.setAdsContainer(R.id.ads);

PotionList potionList = new PotionList(this);
adapter = new PotionListViewAdapter(this, potionList);
listView.setAdapter(adapter);
}

@Bind(R.id.listview)
ListView listView;
@Bind(R.id.editsearch)
EditText editsearch;
@Bind(R.id.Layout_Internet)
RelativeLayout internetLayout;
}

init() 메소드에서 포션 리스트를 불러와서 어댑터에 장착!한다.

그리고 그 어댑터를 리스트뷰에 장착한다! (이상한  @Bind같은거는 ButterKnife 라이브러리 때문...)

EditText에 addTextChangedListener를 달고 다음과 같은 코드를 붙여넣어주면 끝!

계속 toLowerCase하는 이유는 영어 대문자로 검색해도 소문자로된거 찾기 위함이다.