what is wrong with my code? i am getting the entire list as suggestion in autocomplete text view.
public class ContactAdapter extends ArrayAdapter<String> {
List<ContactList> contactLists;
List<ContactList> suggestions;
LayoutInflater inflater;
public ContactAdapter(Activity context, int id, ArrayList list) {
super(context, id,list);
this.contactLists = list;
suggestions = new ArrayList<>();
inflater = (LayoutInflater.from(context));
}
private View getCustomView(final int position, View view, ViewGroup viewGroup){
view = inflater.inflate(R.layout.custom_contact_layout, null);
TextView name = (TextView)view.findViewById(R.id.textView);
TextView email = (TextView)view.findViewById(R.id.textView2);
name.setText(contactLists.get(position).getName());
email.setText(contactLists.get(position).getEmail());
return view;
}
#Override
public View getView(int position , View view , ViewGroup parent)
{
return getCustomView(position,view,parent);
}
#Override
public Filter getFilter() {
Filter nameFilter = new Filter() {
#Override
public CharSequence convertResultToString(Object result) {
return ((ContactList) result).getName();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
suggestions.clear();
for (int contactName = 0; contactName < contactLists.size(); contactName++) {
if (contactLists.get(contactName).getName().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
suggestions.add(contactLists.get(contactName));
Log.d(">add>", contactLists.get(contactName).getName() + "");
}
}
filterResults.values = suggestions;
filterResults.count = suggestions.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
suggestions.clear();
suggestions = (List<ContactList>) results.values;
notifyDataSetChanged();
} else
notifyDataSetInvalidated();
}
};
return nameFilter;
}
}
Tell me how can i get only the filtered results as suggestions.In perform filter method only the filtered results get added. Why it is not getting reflected in publishResults method?
Change your code to:
Log.d(">>","called");
if(results.count >0){
suggestions.clear();
suggestions = (List<ContactList>) results.values;
notifyDataSetChanged();
}
else
notifyDataSetInvalidated();
}
Related
I am trying to implement the search in the Custom ListView. I am able to search in my list. But the problem with my adapter is once the query string is not available in the list even if i backspace my string and write the correct string it's not able to search it. And my other question is how can I refresh the list with my old list which was present before the search.
Here is my code:
public class ChartListAdapter extends BaseAdapter implements Filterable {
ArrayList<ChartModel> list;
Context context;
public ChartListAdapter(ArrayList<ChartModel> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
if(list != null) {
return list.size();
} else {
return 0;
}
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null) {
view = View.inflate(context, R.layout.chart_card, null);
}
TextView chart_name = view.findViewById(R.id.chart_name);
SwitchCompat switchCompat = view.findViewById(R.id.chart_selected);
switchCompat.setTag(list.get(i).getChart_id());
chart_name.setText(list.get(i).getChart_name());
switchCompat.setChecked(list.get(i).getCard_selected());
switchCompat.setOnCheckedChangeListener((compoundButton, b) -> {
String getTag = compoundButton.getTag().toString();
Toast.makeText(context, getTag + " is selected :" + b, Toast.LENGTH_LONG).show();
});
return view;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint == null || constraint.length() == 0){
filterResults.count = list.size();
filterResults.values = list;
}else{
ArrayList<ChartModel> resultsModel = new ArrayList<>();
String searchStr = constraint.toString().toLowerCase();
for(ChartModel itemsModel:list){
if(itemsModel.getChart_id().contains(searchStr)){
resultsModel.add(itemsModel);
}
filterResults.count = resultsModel.size();
filterResults.values = resultsModel;
}
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
list = (ArrayList<ChartModel>) results.values;
notifyDataSetChanged();
}
};
}
}
Any suggestion will be of great help. Thank you for your time.
Change your adapter class like this
public class ChartListAdapter extends BaseAdapter implements Filterable {
ArrayList<ChartModel> list;
ArrayList<ChartModel> filteredList;
Context context;
public ChartListAdapter(ArrayList<ChartModel> list, Context context) {
this.list = list;
this.filteredList = list;
this.context = context;
}
#Override
public int getCount() {
if(filteredList != null) {
return filteredList.size();
} else {
return 0;
}
}
#Override
public Object getItem(int i) {
return filteredList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null) {
view = View.inflate(context, R.layout.chart_card, null);
}
TextView chart_name = view.findViewById(R.id.chart_name);
SwitchCompat switchCompat = view.findViewById(R.id.chart_selected);
switchCompat.setTag(filteredList.get(i).getChart_id());
chart_name.setText(filteredList.get(i).getChart_name());
switchCompat.setChecked(filteredList.get(i).getCard_selected());
switchCompat.setOnCheckedChangeListener((compoundButton, b) -> {
String getTag = compoundButton.getTag().toString();
Toast.makeText(context, getTag + " is selected :" + b, Toast.LENGTH_LONG).show();
});
return view;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint == null || constraint.length() == 0){
filteredList = list;
}else{
ArrayList<ChartModel> resultsModel = new ArrayList<>();
String searchStr = constraint.toString().toLowerCase();
for(ChartModel itemsModel:list){
if(itemsModel.getChart_id().contains(searchStr)){
resultsModel.add(itemsModel);
}
filteredList = resultsModel;
}
}
filterResults.values = filteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredList = (ArrayList<ChartModel>) results.values;
notifyDataSetChanged();
}
};
}
}
This is the code I am using for custom adapter for my autocomplete textview
I tried this solution link
This solution says that item count may be 0 but in my case item count is not 0.
It never goes to getView() method. I try it calling from Fragment, I tried calling it from Activity
I tried solution from this answer as well link but it doesn't work.
It never goes inside the getView() method.
public class BusCityListAdapter extends ArrayAdapter<BusCityList> {
private ArrayList<BusCityList> cityList;
private ArrayList<BusCityList> tempCityList;
private ArrayList<BusCityList> suggestionsList;
public BusCityListAdapter(Context context, ArrayList<BusCityList> objects) {
super(context, android.R.layout.simple_list_item_1, objects);
this.cityList = objects;
this.tempCityList = new ArrayList<BusCityList>(objects);
this.suggestionsList = new ArrayList<BusCityList>(objects);
}
#Override
public int getCount() {
System.out.println("Main List Size=="+cityList.size());
System.out.println("Temp List Size=="+tempCityList.size());
System.out.println("Suggestion List Size=="+suggestionsList.size());
return cityList.size();
}
#Override
public BusCityList getItem(int position) {
return cityList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("Inside GetView");
BusCityList busCity = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.bus_city_name_layout, parent, false);
}
MyTextView bus_name_label = (MyTextView) convertView.findViewById(R.id.bus_name_label);
if (bus_name_label != null)
bus_name_label.setText(busCity.getCity_name());
// Now assign alternate color for rows
return convertView;
}
#Override
public Filter getFilter() {
return myFilter;
}
Filter myFilter = new Filter() {
#Override
public CharSequence convertResultToString(Object resultValue) {
BusCityList busCity = (BusCityList) resultValue;
return busCity.getCity_name();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
suggestionsList.clear();
for (BusCityList city : tempCityList) {
if (city.getCity_name().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
suggestionsList.add(city);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestionsList;
filterResults.count = suggestionsList.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<BusCityList> c = (ArrayList<BusCityList>) results.values;
if (results != null && results.count > 0) {
clear();
for (BusCityList city : c) {
add(city);
notifyDataSetChanged();
}
}
}
};
}
Here is the code where I am setting the adapter to AutoCompleteTextView
AutoCompleteTextView txtToWhere = (AutoCompleteTextView) v.findViewById(R.id.txtToWhere);
busCityListAdapter = new BusCityListAdapter(getActivity(), arrayList);
txtToWhere.setAdapter(busCityListAdapter);
busCityListAdapter.notifyDataSetChanged();
I am working on a basic android app that manages contacts. I am using a custom adapter and a custom listview. I have a class ContactItem that represents each contact. Every contact of the listview is a ContactItem instance. When I implemented my search view the app crashes. I followed that answer but each time I write inside the search to filter the listview, the app crashes.
I would appreciate having some supports because I have been trying to find a solution since February.
Here is my Adapter :
public class CustomAdapter extends ArrayAdapter<ContactItem> implements Filterable {
private Context context;
private ArrayList<ContactItem> arrayList;
public CustomAdapter(#NonNull Context context, int resource, ArrayList<ContactItem> arrayList) {
super(context, resource, arrayList);
this.context = context;
this.arrayList = arrayList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.customlist, parent, false);
TextView nom = (TextView) view.findViewById(R.id.nom);
String nomComplet = arrayList.get(position).getPrenom() + " " +arrayList.get(position).getNom();
nom.setText(nomComplet);
return view;
}
Filter myFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<ContactItem> templist = new ArrayList<ContactItem>();
//constraint is the text you want to filter your list with
//arraylist is the data set we will filter from
if(constraint != null && arrayList !=null){
int length = arrayList.size();
int i ;
String nomComplet;
Integer id;
String nom, prenom,phone,adresse,email;
for(i=0;i<length;i++){
nomComplet = arrayList.get(i).getNom()+" "+ arrayList.get(i).getPrenom();
if(nomComplet.toUpperCase().contains(constraint.toString().toUpperCase())){
ContactItem item = (ContactItem) arrayList.get(i);
templist.add(item);
}
}
filterResults.values = templist;
filterResults.count = templist.size();
}else {
filterResults.values = arrayList;
filterResults.count = arrayList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayList = (ArrayList<ContactItem>) results.values;
if(results.count>0){
notifyDataSetChanged();
}else{
notifyDataSetInvalidated();
}
}
};
#NonNull
#Override
public Filter getFilter() {
return myFilter;
}
}
Please check this one
Filter myFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<ContactItem> tempList=new ArrayList<ContactItem>();
//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<ContactItem>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
Last step,
#Override
public Filter getFilter() {
return myFilter;
}
I am having trouble with Autocomplete Textview where I am calling the list for it through an API
this is the code that I am using for Adapter of the list
class PickDropLocationAdapter extends ArrayAdapter {
ArrayList PickDropBeans, temppickDropBean, suggestions;
public PickDropLocationAdapter(Context context, ArrayList<PickDropBean> objects) {
super(context, android.R.layout.simple_list_item_1, objects);
this.PickDropBeans = objects;
this.temppickDropBean = new ArrayList<PickDropBean>(objects);
this.suggestions = new ArrayList<PickDropBean>(objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
PickDropBean PickDropBean = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_pick_drop, parent, false);
}
TextView txtpickDropBean = (TextView) convertView.findViewById(R.id.tvCustomer);
ImageView ivpickDropBeanImage = (ImageView) convertView.findViewById(R.id.ivCustomerImage);
if (txtpickDropBean != null)
txtpickDropBean.setText(PickDropBean.getLocationname() );
/*if (ivpickDropBeanImage != null && PickDropBean.getProfilePic() != -1)
ivpickDropBeanImage.setImageResource(PickDropBean.getProfilePic());*/
// Now assign alternate color for rows
// if (position % 2 == 0)
// convertView.setBackgroundColor(getContext().getColor(R.color.odd));
// else
// convertView.setBackgroundColor(getContext().getColor(R.color.even));
return convertView;
}
#Override
public Filter getFilter() {
return myFilter;
}
Filter myFilter = new Filter() {
#Override
public CharSequence convertResultToString(Object resultValue) {
PickDropBean PickDropBean = (PickDropBean) resultValue;
return PickDropBean.getLocationname() ;
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
suggestions.clear();
for (PickDropBean people : temppickDropBean) {
if (people.getLocationname().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
suggestions.add(people);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<PickDropBean> c = (ArrayList<PickDropBean>) results.values;
if (results != null && results.count > 0) {
clear();
for (PickDropBean cust : c) {
add(cust);
notifyDataSetChanged();
}
}
}
};
}
And the Volley is used for calling the API within which I am parsing my JSON object through API and then setting the list and the adapter
error is
ava.lang.NullPointerException: collection == null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3133)
My custom adapter for a AutoCompleteTextView always returns all items. results.count is always the correct size, that's why I'm wondering...
public class UniversityAdapter extends ArrayAdapter<University> implements Filterable {
List<University> items = new ArrayList<University>();
List<University> itemsAll = new ArrayList<University>();
private Context context;
int resource;
public UniversityAdapter(Context context, int resId, List<University> items) {
super(context, resId, items);
this.context = context;
this.resource = resId;
this.items = items;
itemsAll.addAll(this.items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(resource, parent, false);
} else {
row = convertView;
}
University university = itemsAll.get(position);
TextView nameView = (TextView) row.findViewById(android.R.id.text1);
nameView.setText(university.getName());
return row;
}
#Override
public Filter getFilter() {
return new Filter() {
public String convertResultToString(Object resultValue) {
String str = ((University) (resultValue)).getName();
return str;
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
List<University> suggestions = new ArrayList<University>();
for (University university : itemsAll) {
if (university.getName().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
suggestions.add(university);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
items = (ArrayList<University>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
}
I think this code is the culprit :
this.items = items;
itemsAll.addAll(this.items); //remove this, use only items
I suggest to remove itemsAll completely because items is enough.
Look at this code :
items = (ArrayList<University>) results.values;
notifyDataSetChanged();
You use items not itemsAll
UPDATE
And change (see my comments) :
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
List<University> universities= (ArrayList<University>) results.values;
items.clear(); //clear the old data
for(University univ : universities)
{
items.add(univ); //add each result
}
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
To get the desired result.