나는 안드로이드에서 목록보기를 만들었고 목록 위에 편집 텍스트를 추가하고 싶습니다. 사용자가 텍스트를 입력하면 목록이 사용자 입력에 따라 필터링됩니다.
안드로이드에서 목록 어댑터를 필터링하는 방법이 있다면 누구든지 제발 말해 줄 수 있습니까?
나는 안드로이드에서 목록보기를 만들었고 목록 위에 편집 텍스트를 추가하고 싶습니다. 사용자가 텍스트를 입력하면 목록이 사용자 입력에 따라 필터링됩니다.
안드로이드에서 목록 어댑터를 필터링하는 방법이 있다면 누구든지 제발 말해 줄 수 있습니까?
답변:
.xml 레이아웃 파일의 목록보기 위에 EditText를 추가합니다. 그리고 당신의 활동 / 조각에서 ..
lv = (ListView) findViewById(R.id.list_view);
inputSearch = (EditText) findViewById(R.id.inputSearch);
// Adding items to listview
adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products);
lv.setAdapter(adapter);
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
@Override
public void afterTextChanged(Editable arg0) {}
});
여기서 기본은 편집 텍스트에 OnTextChangeListener 를 추가 하고 콜백 메서드 내에서 목록보기의 어댑터에 필터를 적용하는 것입니다.
편집하다
사용자 정의 BaseAdapter 구현하는 방법 "LL 필요에 필터를 얻으려면 필터링의 인터페이스를.
class CustomAdapter extends BaseAdapter implements Filterable {
public View getView(){
...
}
public Integer getCount()
{
...
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayListNames = (List<String>) results.values;
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<String> FilteredArrayNames = new ArrayList<String>();
// perform your search here using the searchConstraint String.
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mDatabaseOfNames.size(); i++) {
String dataNames = mDatabaseOfNames.get(i);
if (dataNames.toLowerCase().startsWith(constraint.toString())) {
FilteredArrayNames.add(dataNames);
}
}
results.count = FilteredArrayNames.size();
results.values = FilteredArrayNames;
Log.e("VALUES", results.values.toString());
return results;
}
};
return filter;
}
}
performFiltering () 내부 에서 검색 쿼리를 데이터베이스의 값과 실제 비교해야합니다. 결과를 publishResults () 메서드에 전달합니다 .
필터링 가능한 어댑터 구현 :
public class vJournalAdapter extends ArrayAdapter<JournalModel> implements Filterable{
private ArrayList<JournalModel> items;
private Context mContext;
....
그런 다음 필터 클래스를 만듭니다.
private class JournalFilter extends Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
List<JournalModel> allJournals = getAllJournals();
if(constraint == null || constraint.length() == 0){
result.values = allJournals;
result.count = allJournals.size();
}else{
ArrayList<JournalModel> filteredList = new ArrayList<JournalModel>();
for(JournalModel j: allJournals){
if(j.source.title.contains(constraint))
filteredList.add(j);
}
result.values = filteredList;
result.count = filteredList.size();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
items = (ArrayList<JournalModel>) results.values;
notifyDataSetChanged();
}
}
}
이렇게하면 어댑터가 필터링 가능하므로 필터 항목을 어댑터의 필터로 전달하고 작업을 수행 할 수 있습니다. 도움이 되셨기를 바랍니다.
이 주제에 여전히 관심이있는 경우 목록을 필터링하는 가장 좋은 방법은 일반 필터 클래스를 만들고 Java 구식 SDK 패키지에 포함 된 일부 기본 반사 / 제네릭 기술과 함께 사용하는 것입니다. 내가 한 일은 다음과 같습니다.
public class GenericListFilter<T> extends Filter {
/**
* Copycat constructor
* @param list the original list to be used
*/
public GenericListFilter (List<T> list, String reflectMethodName, ArrayAdapter<T> adapter) {
super ();
mInternalList = new ArrayList<>(list);
mAdapterUsed = adapter;
try {
ParameterizedType stringListType = (ParameterizedType)
getClass().getField("mInternalList").getGenericType();
mCompairMethod =
stringListType.getActualTypeArguments()[0].getClass().getMethod(reflectMethodName);
}
catch (Exception ex) {
Log.w("GenericListFilter", ex.getMessage(), ex);
try {
if (mInternalList.size() > 0) {
T type = mInternalList.get(0);
mCompairMethod = type.getClass().getMethod(reflectMethodName);
}
}
catch (Exception e) {
Log.e("GenericListFilter", e.getMessage(), e);
}
}
}
/**
* Let's filter the data with the given constraint
* @param constraint
* @return
*/
@Override protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<T> filteredContents = new ArrayList<>();
if ( constraint.length() > 0 ) {
try {
for (T obj : mInternalList) {
String result = (String) mCompairMethod.invoke(obj);
if (result.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
filteredContents.add(obj);
}
}
}
catch (Exception ex) {
Log.e("GenericListFilter", ex.getMessage(), ex);
}
}
else {
filteredContents.addAll(mInternalList);
}
results.values = filteredContents;
results.count = filteredContents.size();
return results;
}
/**
* Publish the filtering adapter list
* @param constraint
* @param results
*/
@Override protected void publishResults(CharSequence constraint, FilterResults results) {
mAdapterUsed.clear();
mAdapterUsed.addAll((List<T>) results.values);
if ( results.count == 0 ) {
mAdapterUsed.notifyDataSetInvalidated();
}
else {
mAdapterUsed.notifyDataSetChanged();
}
}
// class properties
private ArrayAdapter<T> mAdapterUsed;
private List<T> mInternalList;
private Method mCompairMethod;
}
이후에해야 할 일은 어댑터 참조, 목록 및 필터링을 위해 호출 할 메서드를 전달하는 멤버 클래스 (View의 "onCreate"내에서 가능)로 필터를 만드는 것입니다.
this.mFilter = new GenericFilter<MyObjectBean> (list, "getName", adapter);
지금 누락 된 유일한 것은 어댑터 클래스의 "getFilter"메서드를 재정의하는 것입니다.
@Override public Filter getFilter () {
return MyViewClass.this.mFilter;
}
완료되었습니다! 목록을 성공적으로 필터링해야합니다. 물론 필요를 설명하는 최상의 방법으로 필터 알고리즘을 구현해야합니다. 아래 코드는 단지 예일뿐입니다. . 도움이 되었기를 바랍니다.