I created custom adapter by extending BaseAdapter and implementing Filterable interface. This adapter is used for suggest phone number to user when they type a contact number or contact person name.ArrayList<String> data contain those data with the pattern of "person name:number" which are extracted from phone.
It's working find except for one issue. If I search for contacts start with letter "A" it's show the data correctly. If I delete that and type "B" again it shows both contacts start with "A" and "B". I know that I have to clear ArrayList<String> matchedResults(Check the code) in some method before add new data but when I did that It gave me an empty ArrayList. In which method at which point I should do that or is there a different solution for this ?
here's the code
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<String> data;
private ArrayList<String> matchedResults = new ArrayList<String>();
public AutoCompleteAdapter(Context context, ArrayList<String> namesAndNumbers) {
this.context = context;
this.data = namesAndNumbers;
}
#Override
public int getCount() {
return matchedResults.size();
}
#Override
public String getItem(int position) {
return matchedResults.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, parent, false);
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView numberTextView = (TextView) view.findViewById(R.id.number);
String[] split = matchedResults.get(position).split(":");
nameTextView.setText(split[0]);
numberTextView.setText(split[1]);
return view;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null || constraint.length() != 0) {
for (String loop:data) {
int charSequenceSize = constraint.length();
if(onlyText(constraint.toString()) && !matchedResults.contains(loop)){
String[] split = loop.split(":");
String substring = split[0].substring(0, charSequenceSize);
if (substring.equalsIgnoreCase(constraint.toString())){
matchedResults.add(loop);
}
}else if(onlyNumbers(constraint.toString())){
String[] split = loop.split(":");
String substring = split[1].substring(0, charSequenceSize);
if (substring.equals(constraint.toString()) && !matchedResults.contains(loop) ){
matchedResults.add(loop);
}
}
}
}
results.values = matchedResults;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
results.values = matchedResults;
notifyDataSetChanged();
}
};
}
public boolean onlyText(String text) {
boolean result = false;
if (Pattern.matches("[a-zA-Z ]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
public boolean onlyNumbers(String text) {
boolean result = false;
if (Pattern.matches("[0-9+]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
}
update your filter to this
#Override
public Filter getFilter() {
return nameFilter;
}
Filter nameFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
matchedResults.clear();
for (String item : data) {
if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
matchedResults.add(item);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = matchedResults;
filterResults.count = matchedResults.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<String> filteredList = (ArrayList<String>) results.values;
if (results != null && results.count > 0) {
data.clear();
for (String c : filteredList) {
data.add(c);
}
notifyDataSetChanged();
}
}
};
So your entire code it be like this :
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<String> data;
private ArrayList<String> matchedResults = new ArrayList<String>();
public AutoCompleteAdapter(Context context, ArrayList<String> namesAndNumbers) {
this.context = context;
this.data = namesAndNumbers;
}
#Override
public int getCount() {
return matchedResults.size();
}
#Override
public String getItem(int position) {
return matchedResults.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, parent, false);
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView numberTextView = (TextView) view.findViewById(R.id.number);
String[] split = matchedResults.get(position).split(":");
nameTextView.setText(split[0]);
numberTextView.setText(split[1]);
return view;
}
#Override
public Filter getFilter() {
return nameFilter;
}
Filter nameFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
matchedResults.clear();
for (String item : data) {
if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
matchedResults.add(item);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = matchedResults;
filterResults.count = matchedResults.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<String> filteredList = (ArrayList<String>) results.values;
if (results != null && results.count > 0) {
data.clear();
for (String c : filteredList) {
data.add(c);
}
notifyDataSetChanged();
}
}
};
public boolean onlyText(String text) {
boolean result = false;
if (Pattern.matches("[a-zA-Z ]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
public boolean onlyNumbers(String text) {
boolean result = false;
if (Pattern.matches("[0-9+]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
}
I hope to be helpful for you .
Related
on JDK 1.8
tried casting many ways but none working for me.
public class CountryAdapter extends ArrayAdapter<CountryModel> {
private Context context;
private List<CountryModel> countryModelList;
private List<CountryModel> countryModelListFiltered;
public CountryAdapter(Context context, List<CountryModel> countryModelList) {
super(context, R.layout.custom_list_item, countryModelList);
this.context = context;
this.countryModelList = countryModelList;
this.countryModelListFiltered = countryModelList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//Instantiates a layout XML file into its corresponding View objects.
#SuppressLint("ViewHolder")
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_list_item, null, true);
TextView tvCountryName = view.findViewById(R.id.tvCountryName);
ImageView countryFlag = view.findViewById(R.id.imageFlag);
tvCountryName.setText(countryModelListFiltered.get(position).getCountry());
//using glide library to set image to image View.
Glide.with(context).load(countryModelListFiltered.get(position).getFlag()).into(countryFlag);
return view;
}
#Override
public int getCount() {
return countryModelListFiltered.size();
}
#Nullable
#Override
public CountryModel getItem(int position) {
return countryModelListFiltered.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
//Filter Logic
#NonNull
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint == null || constraint.length() == 0) {
filterResults.count = countryModelList.size();
filterResults.values = countryModelList;
} else {
List<CountryModel> resultModel = new ArrayList<>();
String searchString = constraint.toString().toLowerCase();
for (CountryModel itemModel:countryModelList) {
if (itemModel.getCountry().toLowerCase().contains(searchString)) {
resultModel.add(itemModel);
}
filterResults.count = resultModel.size();
filterResults.values = itemModel;
}
}
return filterResults;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Log.d("Cast:", "publishResults: " + results.values.toString());
countryModelListFiltered = ((List<CountryModel>) results.values);
AffectedCountries.countryModelList = (List<CountryModel>) results.values;
notifyDataSetChanged();
}
};
return filter;
}
}
I have checked you code .. problem is you are assigning wrong value to filterResults also at wrong place (inside loop). Your code should look like below .
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint == null || constraint.length() == 0) {
filterResults.count = countryModelList.size();
filterResults.values = countryModelList;
} else {
List<CountryModel> resultModel = new ArrayList<>();
String searchString = constraint.toString().toLowerCase();
for (CountryModel itemModel:countryModelList) {
if (itemModel.getCountry().toLowerCase().contains(searchString)) {
resultModel.add(itemModel);
}
}
filterResults.count = resultModel.size();
filterResults.values = resultModel;
}
return filterResults;
}
I am implementing autosearchTextView and I am getting data from web service.The API get hit when char value is 3. I refer this link https://github.com/kyasar/markod/blob/master/app/src/main/java/com/dopamin/markod/adapter/ProductSearchAdapter.java. and this is also
http://makovkastar.github.io/blog/2014/04/12/android-autocompletetextview-with-suggestions-from-a-web-service/
When I enter 3 char the publishResults() method trigger and so getting no drop down. I debugged and I found web service get called and but before it This publishResults() method triggered. I have to spend a lot of time to do in R&D. Please Help me out.
mMutualFundAdapter = new PrimaryContractAdapter(CreateNoteActivityNew.this); primary_atv.setThreshold(3);//will start working from 3 character
//setting the adapter data into the AutoCompleteTextView
primary_atv.setAdapter(mMutualFundAdapter);
primary_atv.setLoadingIndicator(
(android.widget.ProgressBar) findViewById(R.id.pb_loading_indicator));
primary_atv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
PrimaryContract primaryContract = (PrimaryContract) adapterView.getItemAtPosition(position);
primary_atv.setText(primaryContract.getContract());
}
});
Adapter -
public PrimarySearchAdapter(Context context, ArrayList<PrimaryContract> resultList) {
mContext = context;
this.resultList = resultList;
}
#Override
public int getCount() {
return resultList.size();
}
#Override
public PrimaryContract getItem(int index) {
return resultList.get(index);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drop_down_layout, parent, false);
}
((TextView) convertView.findViewById(R.id.heading)).setText(getItem(position).getText());
return convertView;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
findData(mContext, constraint.toString());
if (contractArrayList != null && contractArrayList.size()>0) {
// Assign the data to the FilterResults
filterResults.values = contractArrayList;
filterResults.count = contractArrayList.size();
}
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
resultList = ( ArrayList<PrimaryContract>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}};
return filter;
}
private void findData(Context context, String bookTitle) {
// this finddata() for getting response from REST API using retrofit
contractArrayList = new ArrayList<>();
String url = "http://se.com/publisher_api/primaryContracts?keyword=";
url = url + bookTitle;
ApiRequestResponse apiRequestResponse = new ApiRequestResponse();
final OnResponseReceiveEvent onResponseReceiveEvent = new OnResponseReceiveEvent() {
#Override
public void getSuccess(Object obj) {
if (obj != null) {
createNoteModel = (CreateNoteModel) obj;
if (createNoteModel.getPrimaryContracts() != null && createNoteModel.getPrimaryContracts().size()>0){
if (contractArrayList != null) {
contractArrayList.clear();
contractArrayList = createNoteModel.getPrimaryContracts();
}
}
}
notifyDataSetChanged();
}
// I have followed as I given two links
#Override
public Object getFailure() {
return null;
}
};
apiRequestResponse.getDropDownData(onResponseReceiveEvent, url);
}
}
I have a list of merchants, I am applying filter to it to search by address or a name, filter works fine. it gives proper list of filtered results. But if I again empty the edit text I should see the original list, but I see different count than the original.
Example, in list I have 7 merchants, I do filter it and it shows two filtered merchants in the list, and now if I empty the edit text I see only 5 merchants , unable to see the original list of 7 merchants.
Adapter:
public class SearchedMerchantsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
static final int LOAD_MERCHANTS = 0;
private Context context;
public ArrayList<Merchants> list;
public ArrayList<Merchants> baselist = new ArrayList<>();
public SearchedMerchantsAdapter(Context context, ArrayList<Merchants> list) {
this.context = context;
this.list = list;
this.baselist = list;
}
#Override
public int getItemViewType(int position) {
Object obj = list.get(position);
if (obj instanceof Merchants) return LOAD_MERCHANTS;
return super.getItemViewType(position);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = holder.getItemViewType();
switch (viewType) {
case LOAD_MERCHANTS:
LoadSearchedMerchants loadSearchedMerchants = (LoadSearchedMerchants) holder;
retriveAllMerchants(loadSearchedMerchants, position);
break;
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (viewType) {
case LOAD_MERCHANTS:
View v_image_msg = inflater.inflate(R.layout.search_merchant_layout, parent, false);
viewHolder = new LoadSearchedMerchants(v_image_msg);
break;
}
return viewHolder;
}
#Override
public int getItemCount() {
return list.size();
}
public void retriveAllMerchants(final LoadSearchedMerchants holder, int position) {
final Merchants data = (Merchants) list.get(position);
holder.tv_kiarana_name.setText(data.getKirana_name());
holder.tv_address.setText(data.getMerchant_address());
holder.lay_row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, MerchantProfileActivity.class);
i.putExtra("cont_name",data.getMerchant_name());
i.putExtra("kirana_name",data.getKirana_name());
i.putExtra("email_id",data.getEmail_id());
i.putExtra("phone_no",data.getPhone());
i.putExtra("address",data.getMerchant_address());
context.startActivity(i);
}
});
holder.btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final SessionData sessionData;
final String sessionUserId,access_token;
sessionData=new SessionData(context);
sessionUserId = sessionData.getString("user_id","-1");
access_token = sessionData.getString("api_key", "-1");
new SendRequestAsyncTask(context).execute(sessionUserId,access_token,data.getMerchant_id().toString());
}
});
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Merchants> results = new ArrayList<>();
if (constraint != null) {
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(constraint.toString()) || g.getMerchant_address().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
list = (ArrayList<Merchants>) results.values;
notifyDataSetChanged();
}
};
}
}
What can be the reason for this? Thank you..
Create this method in adapter:
public Item getItemAtPosition(int position)
{
return list.get(position);
}
Now, when click action occurs just call this method:
adapter.getItemAtPosition(position).getMerchant_name()
Can you try this ?
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Merchants> results = new ArrayList<>();
if (charSequence != null && charSequence.length() > 0) {
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(constraint.toString()) || g.getMerchant_address().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
oReturn.count = results.size();
}
else
{
oReturn.values = baselist;
oReturn.count = baselist.size();
}
return oReturn;
}
Update
Create one Method in Adapter.. Comment out getFilter() and interface Filterable
public void filterData(String compareString)
{
list.clear();
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(compareString) || g.getMerchant_address().contains(compareString))
list.add(g);
}
}
notifyDataSetChanged();
}
And Last call this Method From your edittext change listener
like adapter.filterData("StringwhichisChangedFromEdittext")
Hope this help.
Return the entire list if user enters nothing
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Merchants> results = new ArrayList<>();
if(TextUtils.isEmpty(constraint)){
oReturn.values = baselist==null?new ArrayList() : baselist ;
return oReturn.values ;
}
if (constraint != null) {
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(constraint.toString()) || g.getMerchant_address().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
list = (ArrayList<Merchants>) results.values;
notifyDataSetChanged();
}
};
}
I am implementing a filter to my custom object list. Filter is working, but if I filter the list I get the filtered result list and again if I try to filter with different word the list seems empty.
Original list is not seen when filtered.
Adapter :
public class ItemsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable{
static final int LOAD_ORDERITEMS = 0;
private Context context;
private List<OrderItem> list;
private AddOrderFragment addOrderFragment;
public ItemsAdapter(Context context, List<OrderItem> list) {
this.context = context;
this.list = list;
this.addOrderFragment = addOrderFragment;
}
#Override
public int getItemViewType(int position) {
Object obj = list.get(position);
if (obj instanceof OrderItem) return LOAD_ORDERITEMS;
return super.getItemViewType(position);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = holder.getItemViewType();
switch (viewType) {
case LOAD_ORDERITEMS:
LoadOrderItemsHolder loadOrderItemsHolder = (LoadOrderItemsHolder) holder;
retrieveAllOrderItem(loadOrderItemsHolder,position);
break;
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (viewType) {
case LOAD_ORDERITEMS:
View v_image_msg = inflater.inflate(R.layout.item_layout, parent, false);
viewHolder = new LoadOrderItemsHolder(v_image_msg);
break;
}
return viewHolder;
}
#Override
public int getItemCount() {
return list.size();
}
public void retrieveAllOrderItem(final LoadOrderItemsHolder holder, int position) {
final OrderItem data = (OrderItem) list.get(position);
holder.txtItemName.setText(data.getItemName());
String unit = data.getQuantity() + " " + data.getUnit();
holder.txtItemQty.setText(unit);
holder.relativeRow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((SearchActivity)context).linearLayoutRecycleView.setVisibility(View.GONE);
((SearchActivity)context).textInput_Item_Unit.setVisibility(View.VISIBLE);
((SearchActivity)context).textInput_Item_quantity.setVisibility(View.VISIBLE);
((SearchActivity)context).textInput_Item_name.setBackgroundResource(0);
((SearchActivity)context).edt_Item_Name.setText(data.getItemName());
((SearchActivity)context).edt_Item_quantity.setText(data.getQuantity());
((SearchActivity)context).edt_Item_Unit.setText(data.getUnit());
}
});
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<OrderItem> results = new ArrayList<OrderItem>();
if (constraint != null) {
if (list != null && list.size() > 0) {
for (final OrderItem g : list) {
if (g.getItemName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
list = (ArrayList<OrderItem>) results.values;
notifyDataSetChanged();
}
};
}
}
Please help.. Thank you..
Use this code
static final int LOAD_ORDERITEMS = 0;
private Context context;
private List<OrderItem> list;
private List<OrderItem> baselist = new ArrayList<>();
private AddOrderFragment addOrderFragment;
public ItemsAdapter(Context context, List<OrderItem> list) {
this.context = context;
this.list = list;
this.baselist = list;
this.addOrderFragment = addOrderFragment;
}
And in Filter
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<OrderItem> results = new ArrayList<OrderItem>();
if (constraint != null) {
if (baselist != null && baselist.size() > 0) {
for (final OrderItem g : baselist ) {
if (g.getItemName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
list = (ArrayList<OrderItem>) results.values;
notifyDataSetChanged();
}
};
}
As We need to store original list in separate array list, we need to get filter data from that.
My question is when i filter listview with baseadapter than i got perfect result but after click on this item,i can't get related values of that item but i get wrong position item so notifydatasetchenged not work.
'public ConsultationAdpater(Context context, ArrayList<Doctor> doctors) {
this.context = context;
this.doctorList = doctors;
this.mStringFilterList = doctors;
getFilter();
imageLoader = ImageLoader.getInstance();
this.inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// set options for image display
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.activity_indicator)
.showImageForEmptyUri(R.drawable.image_not_available)
.showImageOnFail(R.drawable.image_not_available)
.resetViewBeforeLoading(true).cacheInMemory(true)
.cacheOnDisk(true).considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
#Override
public int getCount() {
return doctorList.size();
}
#Override
public Object getItem(int position) {
return doctorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.row_consult, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) convertView
.findViewById(R.id.img_row_const);
holder.txtName = (TextView) convertView
.findViewById(R.id.tDtNm_row_const);
holder.txtSpeciality = (TextView) convertView
.findViewById(R.id.tDtPt_row_const);
holder.txtPrice = (TextView) convertView
.findViewById(R.id.tDtPr_row_const);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Doctor doctor = doctorList.get(position);
holder.txtName.setText(doctor.base_user.first_name);
holder.txtSpeciality.setText(doctor.specialization);
holder.txtPrice.setText(doctor.cost_per_minute + "$/min");
if (images[position] == null) {
holder.image.setImageResource(R.drawable.image_not_available);
} else {
imageLoader.displayImage(
"http://37.252.121.94/" + images[position], holder.image,
options);
}
return convertView;
}
public void switchDoctorList(ArrayList<Doctor> doctors, String[] images) {
this.doctorList = doctors;
this.mStringFilterList = doctors;
this.images = images;
this.notifyDataSetChanged();
}
public void switchDoctorList(ArrayList<Doctor> doctors) {
this.doctorList = doctors;
this.mStringFilterList = doctors;
this.notifyDataSetChanged();
}
private static class ViewHolder {
ImageView image;
TextView txtName;
TextView txtSpeciality;
TextView txtPrice;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
// Invoked in a worker thread to filter the data according to the
// constraint.
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Doctor> filterList = new ArrayList<Doctor>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).specialization.toUpperCase())
.contains(constraint.toString().toUpperCase())) {
filterList.add(mStringFilterList.get(i));
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
// Invoked in the UI thread to publish the filtering results in the user
// interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
doctorList = (ArrayList<Doctor>) results.values;
notifyDataSetChanged();
}
}
}'
This worked for me
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
//abrirActividadDetallada(position, id);
Object MyObject=(Object) parent.getAdapter().getItem(position);
CustomMethod(MyObject);
}
});
the ideology of filtering in adapters works by replacing the original data list int he adapter with the filtered list. The performFiltering method will tell you what elements in the data list match your filter. But not this list makes the primary data list for your adapter instead of the original data list. So you shoudl keep 2 lists in your adapter.
The original unfiltered list. for reference
The second list which feeds data to the adapter. getView and getItems etc. methods should use this list.
When you do performFiltering use the original unfiltered list to extract matching data elements and save in the second list. That way you will never go wrong.
Sample Example adapter for reference
public class CompanyQuotesResultAdapter extends BaseAdapter{
//original data populated from DB or web service.
private ArrayList<MyDataVO> originalData;
//the data list which the adapter uses for its work
private ArrayList<MyDataVO> data;
private LayoutInflater inflater = null;
private Fragment parentFragment;
private Filter dataFilter;
private int quoteGreenColor = -1;
public CompanyQuotesResultAdapter(Fragment parentFragment){
//set values here
}
public ArrayList<MyDataVO> getData() {
return new ArrayList<MyDataVO>(this.data);
}
public ArrayList<MyDataVO> getOriginalData() {
return new ArrayList<MyDataVO>(this.originalData);
}
public void addDataVOsWithoutNotification(List<MyDataVO> dataVOs){
this.data.addAll(dataVOs);
this.originalData.addAll(dataVOs);
}
public void setData(List<MyDataVO> data) {
this.data = new ArrayList<MyDataVO>(data);
this.originalData = new ArrayList<MyDataVO>(data);
this.notifyDataSetChanged();
}
public boolean isEmpty() {
return this.data.isEmpty();
}
public void clearAll(){
this.originalData.clear();
this.data.clear();
this.notifyDataSetChanged();
}
public void clearAllWithoutNotification(){
this.data.clear();
this.originalData.clear();
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public Filter getFilter(){
return dataFilter;
}
//Filtering class
private class ArrayFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (prefix == null || prefix.length() == 0) {
ArrayList<MyDataVO> list = new ArrayList<MyDataVO>(originalData);
results.values = list;
results.count = list.size();
} else {
String prefixString = prefix.toString().toLowerCase(Locale.ENGLISH);
ArrayList<MyDataVO> values = new ArrayList<MyDataVO>(originalData);
final int count = values.size();
final ArrayList<MyDataVO> newValues = new ArrayList<MyDataVO>();
for (int i = 0; i < count; i++) {
final MyDataVO resultRowVO = values.get(i);
final String valueText = resultRowVO.getCompanyName().toLowerCase(Locale.ENGLISH);
// First match against the whole, non-splitted value
if (valueText.contains(prefixString)) {
newValues.add(resultRowVO);
}else{
final String codeValueText = resultRowVO.getCompanyCode().toLowerCase(Locale.ENGLISH);
if (codeValueText.contains(prefixString)) {
newValues.add(resultRowVO);
}
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
protected void publishResults(CharSequence constraint, FilterResults results) {
data = (ArrayList<MyDataVO>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}