Пользовательский getFilter в пользовательском массиве ArrayAdapter в android

У меня возникли проблемы с реализацией пользовательского getFilter в пользовательском массиве. На самом деле я понятия не имею, как его реализовать. Пробовал разные коды, но все равно не повезло. Вот мой пользовательский адаптер массива.

package com.test.FilterableList.Adapters; import java.util.ArrayList; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; import com.test.FilterableList.Models.ListTO; import com.test.FilterableList.R; import android.widget.Filterable; public class FilterableAdapter extends ArrayAdapter<ListTO> implements Filterable { // declaring our ArrayList of items public ArrayList<ListTO> objects; /* here we must override the constructor for ArrayAdapter * the only variable we care about now is ArrayList<Item> objects, * because it is the list of objects we want to display. */ public FilterableAdapter(Context context, int textViewResourceId, ArrayList<ListTO> objects) { super(context, textViewResourceId, objects); this.objects = objects; } /* * we are overriding the getView method here - this is what defines how each * list item will look. */ public View getView(int position, View convertView, ViewGroup parent){ // assign the view we are converting to a local variable View v = convertView; // first check to see if the view is null. if so, we have to inflate it. // to inflate it basically means to render, or show, the view. if (v == null) { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = inflater.inflate(R.layout.list_item, null); } /* * Recall that the variable position is sent in as an argument to this method. * The variable simply refers to the position of the current object in the list. (The ArrayAdapter * iterates through the list we sent it) * * Therefore, i refers to the current Item object. */ ListTO i = objects.get(position); if (i != null) { // This is how you obtain a reference to the TextViews. // These TextViews are created in the XML files we defined. TextView tt = (TextView) v.findViewById(R.id.list_name); if (tt != null){ tt.setText(i.FileName); } } // the view must be returned to our activity return v; } } 

И вот класс ListTO.

 package com.test.FilterableList.Models; public class ListTO { public int Id; public String FileName; public String FileUri; public ListTO(int id, String fileName, String fileUri) { Id = id; FileName = fileName; FileUri = fileUri; } } 

И вот макет.

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@drawable/blacklikenbackground" tools:context=".AllListActivity" > <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Search" android:id="@+id/inputSearch" /> <ListView android:id="@+id/test_list" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout> 

Здесь ключевое слово поиска происходит из «inputSearch» EditText.

Вот текст, поменявший слушателя.

  inputSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text // Toast.makeText(getActivity(), cs.toString(), Toast.LENGTH_LONG).show(); m_adapter.getFilter().filter(cs); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable arg0) { // TODO Auto-generated method stub } }); 

Благодарю.

Solutions Collecting From Web of "Пользовательский getFilter в пользовательском массиве ArrayAdapter в android"

У вас проблемы, главным образом потому, что вы используете пользовательский объект. Если вы передадите значение String или int в адаптер массива, вы знаете, как его фильтровать. Но если вы передаете пользовательский фильтр, фильтр по умолчанию не имеет понятия, как с этим бороться.

Хотя непонятно, что вы пытаетесь сделать в своем фильтре, я рекомендую вам следующие шаги.

  1. Правильная реализация ListTO , хотя она не имеет ничего общего с вашей целью прямо сейчас
  2. Внедрение настраиваемого фильтра
  3. Вернуть свой фильтр

Внедрение настраиваемого фильтра

Первое, что вам нужно сделать, – это implements Filterable из вашего адаптера массива.

Во-вторых, обеспечить реализацию вашего Filter

 Filter myFilter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); ArrayList<ListTO> tempList=new ArrayList<ListTO>(); //constraint is the result from text you want to filter against. //objects is your data set you will filter from if(constraint != null && objects!=null) { int length=objects.size(); int i=0; while(i<length){ ListTO item=objects.get(i); //do whatever you wanna do here //adding result set output array tempList.add(item); i++; } //following two lines is very important //as publish result can only take FilterResults objects filterResults.values = tempList; filterResults.count = tempList.size(); } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence contraint, FilterResults results) { objects = (ArrayList<ListTO>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; в Filter myFilter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); ArrayList<ListTO> tempList=new ArrayList<ListTO>(); //constraint is the result from text you want to filter against. //objects is your data set you will filter from if(constraint != null && objects!=null) { int length=objects.size(); int i=0; while(i<length){ ListTO item=objects.get(i); //do whatever you wanna do here //adding result set output array tempList.add(item); i++; } //following two lines is very important //as publish result can only take FilterResults objects filterResults.values = tempList; filterResults.count = tempList.size(); } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence contraint, FilterResults results) { objects = (ArrayList<ListTO>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; 

Последний шаг,

 @Override public Filter getFilter() { return myFilter; } 

Вам необходимо переопределить метод getFilter() в адаптере и предоставить собственный фильтр. Взгляните в этот пример фильтра, чтобы увидеть фактическую реализацию.

Добавьте следующий код getFilter() в класс FilterableAdapter и заполните его фильтрацией:

 /* (non-Javadoc) * @see android.widget.ArrayAdapter#getFilter() */ @Override public Filter getFilter() { return new Filter() { /* (non-Javadoc) * @see android.widget.Filter#performFiltering(java.lang.CharSequence) */ @Override protected FilterResults performFiltering(CharSequence constraint) { // TODO Auto-generated method stub /* * Here, you take the constraint and let it run against the array * You return the result in the object of FilterResults in a form * you can read later in publichResults. */ return null; } /* (non-Javadoc) * @see android.widget.Filter#publishResults(java.lang.CharSequence, android.widget.Filter.FilterResults) */ @Override protected void publishResults(CharSequence constraint, FilterResults results) { // TODO Auto-generated method stub /* * Here, you take the result, put it into Adapters array * and inform about the the change in data. */ } }; } 

Я добавил подсказки, что делать в комментариях.

Нет необходимости писать массивный адаптер. Напишите метод toString (), который должен вернуть значение имени файла.

подобно

 public class ListTO { public int Id; public String FileName; public String FileUri; public ListTO(int id, String fileName, String fileUri) { Id = id; FileName = fileName; FileUri = fileUri; } public String toString(){ return FileName } } 

попробуй это:

  public class Adptr extends BaseAdapter implements Filterable { public ArrayList<Model> modelValues; private Activity activity; private LayoutInflater layoutinflater; private List<Model> mOriginalValues; private int PositionSelected = 0; public Adptr (ArrayList<Model> modelValues, Activity activity) { super(); this.modelValues = modelValues; this.activity = activity; } @Override public int getCount() { return modelValues.size(); } @Override public Object getItem(int position) { return modelValues.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { layoutinflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); ViewHolder holder = null; Model model = modelValues.get(position); if (convertView == null || !(convertView.getTag() instanceof ViewHolder)) { convertView = layoutinflater.inflate(R.layout.row_search, null); holder = new ViewHolder(); holder.txtName = (TextView) convertView.findViewById(R.id.row_serch_txt_name); convertView.setTag(holder); convertView.setTag(R.id.row_serch_txt_name, holder.txtName); } else { holder = (ViewHolder) convertView.getTag(); } holder.txtArtistName.setText("" + modelValue.get_NAME()); return convertView; } class ViewHolder { TextView txtName; } @Override public Filter getFilter() { Filter filter = new Filter() { @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { modelValues = (ArrayList<ModelValueArtist>) results.values; // has notifyDataSetChanged(); } @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); // Holds the // results of a // filtering // operation in // values // List<String> FilteredArrList = new ArrayList<String>(); List<Model> FilteredArrList = new ArrayList<Model>(); if (mOriginalValues == null) { mOriginalValues = new ArrayList<Model>(modelValues); // saves } /******** * * If constraint(CharSequence that is received) is null returns * the mOriginalValues(Original) values else does the Filtering * and returns FilteredArrList(Filtered) * ********/ if (constraint == null || constraint.length() == 0) { // set the Original result to return results.count = mOriginalValues.size(); results.values = mOriginalValues; } else { Locale locale = Locale.getDefault(); constraint = constraint.toString().toLowerCase(locale); for (int i = 0; i < mOriginalValues.size(); i++) { Model model = mOriginalValues.get(i); String data = model.get_NAME(); if (data.toLowerCase(locale).contains(constraint.toString())) { FilteredArrList.add(modelMyMall); } } // set the Filtered result to return results.count = FilteredArrList.size(); results.values = FilteredArrList; } return results; } }; return filter; } } 

Вы можете переопределить toString () в пользовательском классе объекта и вернуть объект String, который вы хотите отфильтровать.

 @Override public void toString(){ return this.toBeFilteredString; } 

А затем просто используйте встроенный по умолчанию фильтр arrayAdapter и вызовите его, используя

 adapter.getFilter().filter(Charsequence c); 

Как вы сказали: «Я хочу реализовать автоматическую подсказку как функцию, используемую в google, но вот из списка – Redone»

Существует еще один способ сделать это, используя AutoCompleteTextView

Для получения дополнительной информации перейдите в AutoCompleteTextView

OutPut будет выглядеть так:

Если ввести charachter 'a', он покажет список слов, начинающихся с 'a'

Введите описание изображения здесь

main.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listitem_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#e2e2e2" android:orientation="vertical" > <AutoCompleteTextView android:id="@+id/autocomplete" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:background="@drawable/text_area" android:inputType="text|textNoSuggestions|textMultiLine" android:paddingLeft="10dp" android:popupBackground="#EFEEEC" android:textColor="#333333" android:textColorHint="#9c9c9c" android:textSize="18sp" android:completionThreshold="1" /> </LinearLayout> 

auto_textview.xml

 <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="12dp" android:textColor="#333333" android:layout_margin="15dp" android:textSize="16sp" > </TextView> 

MainActivity.java

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AutoCompleteTextView seachView = (AutoCompleteTextView) findViewById(R.id.autocomplete); seachView.setAdapter(new ArrayAdapter<String>(this, R.layout.auto_textview, getHeading())); } /** * @return */ public List<String> getHeading() { List<String> list = new ArrayList<String>(); list.add("Android"); list.add("Arnold"); list.add("Blackberry"); list.add("Blackpearl"); list.add("Country"); list.add("Canada"); list.add("City"); list.add("Street Address"); list.add("Objective C"); return list; } } 

Надеюсь, что это поможет вам.