自定义getFilter在android中的自定义ArrayAdapter
我无法在自定义的arrayAdapter中实现自定义的getFilter。 其实我不知道如何去实现它。 尝试了各种代码,但仍然没有运气。 这是我的自定义arrays适配器。
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>
这里的search关键字来自“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 } });
谢谢。
你有问题,主要是因为你正在使用自定义对象。 如果你传递一个String或者int值给数组适配器,那么它就知道如何过滤它。 但是如果你传递自定义对象的默认filter实现不知道如何处理。
虽然目前还不清楚你在filter上做什么,但我build议你遵循以下步骤。
- 正确实施
ListTO
,尽pipe目前与您的目标无关 - 实施自定义filter
- 返回你的filter
实施自定义filter
首先你需要做的是从你的arrays适配器中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(); } } };
最后一步,
@Override public Filter getFilter() { return myFilter; }
您需要重写适配器中的getFilter()
方法,并提供您自己的filter。 看看这个可过滤的例子看看一个实际的实现。
将下面的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. */ } }; }
我已经添加了提示在评论中做什么。
无需编写arrays适配器。 写一个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的默认内置filter并使用它
adapter.getFilter().filter(Charsequence c);
正如你所说的“我要实现自动build议像谷歌使用的function;但这里从列表视图。 – 重做”
还有另一种方法可以通过使用AutoCompleteTextView来完成此操作
有关更多详细信息,请通过AutoCompleteTextView
OutPut看起来像这样
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; } }
希望这会帮助你。