Zapnologica
Zapnologica

Reputation: 22556

Android Custom listView Adapter Filter not going back to original list

I have edited my Adapter class and extended the filterable class. My search functionality works but i am unable to go back to the original content if I backspace everything in the search menu.

here is my adapter class:

public class Menu_List_Item_Adapter extends BaseAdapter implements Filterable {
Context context;
List<FoodMenuRowItem> rowItems;

public Menu_List_Item_Adapter(Context context, List<FoodMenuRowItem> items) {
    this.context = context;
    this.rowItems = items;
}   
private class ViewHolder {
    ImageView imageView;
    TextView txtTitle;
    TextView txtDesc;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;

    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.food_menu_item_list_row,
                null);
        holder = new ViewHolder();
        holder.txtDesc = (TextView) convertView.findViewById(R.id.price);
        holder.txtTitle = (TextView) convertView
                .findViewById(R.id.description);
        holder.imageView = (ImageView) convertView.findViewById(R.id.img);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    FoodMenuRowItem rowItem = (FoodMenuRowItem) getItem(position);

    holder.txtDesc.setText(rowItem.getDesc());
    holder.txtTitle.setText(rowItem.getTitle());
    holder.imageView.setImageResource(rowItem.getImageId());

    return convertView;
}

@Override
public int getCount() {
    return rowItems.size();
}

@Override
public Object getItem(int position) {
    return rowItems.get(position);
}

@Override
public long getItemId(int position) {
    return rowItems.indexOf(getItem(position));
}

@Override
public Filter getFilter() {
    return new Filter() {
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            if (results.count == 0)
                notifyDataSetInvalidated();
            else {
                rowItems = (List<FoodMenuRowItem>) results.values;
                Menu_List_Item_Adapter.this.notifyDataSetChanged();
            }

        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();

            if (constraint == null || constraint.length() == 0) {
                // No filter implemented we return all the list
                results.values = rowItems;
                results.count = rowItems.size();

            } else { // We perform filtering operation
                List<FoodMenuRowItem> filteredRowItems = new ArrayList<FoodMenuRowItem>();

                for (FoodMenuRowItem p : rowItems) {
                    if (p.getName()
                            .toUpperCase()
                            .startsWith(constraint.toString().toUpperCase())) {
                        filteredRowItems.add(p);
                    }
                }
                results.values = filteredRowItems;
                results.count = filteredRowItems.size();
            }
            return results;
        }
    };
}

}

I do check if the results are zero or null and if so to return the original list? What am I missing?

Upvotes: 0

Views: 4035

Answers (3)

Muhamed Riyas M
Muhamed Riyas M

Reputation: 5173

Please follow the changes.

  1. Create a temporary variable to store the initial data

    List<FoodMenuRowItem> tempitems=new ArrayList<FoodMenuRowItem>();
    
  2. Initialize the temperory variable in your constructor

        this.tempitems=items;
    
  3. Replace the for loop in the performFiltering method to

            for (int i = 0; i < tempitems.size(); i++) {
            filterableString = tempitems.get(i);
            if (filterableString.getUserName().toLowerCase()
                    .contains(filterString)) {
                Filtered_Names.add(filterableString);
    
                Log.v("riyas:" + filterableString.getUserName(),
                        "riyas filtering");
            }
        }
    

Upvotes: 0

mrsus
mrsus

Reputation: 5486

it does not go back to original list because when you pass the list of objects to custom adapter, adapter refers the address of list, and when you search something it changes the list which was at that address. But when you press backspace adapter does not restore the list. So point is we have create another List<Object> nlist = new ArrayList<Object>(originalList); it means that a list is generated at another location with same content. Now use nlist to restore the list.

Upvotes: 1

yahya
yahya

Reputation: 4860

You should store your rowItems to get back to it, and then after getting empty text on search area, you should restore that array into rowItems so adapter can reload itself. Something like:

public class Menu_List_Item_Adapter extends BaseAdapter implements Filterable {
Context context;
List<FoodMenuRowItem> rowItems;
List<FoodMenuRowItem> storedRowItems;

public Menu_List_Item_Adapter(Context context, List<FoodMenuRowItem> items) {
this.context = context;
this.rowItems = items;
this.storedRowItems = new List<FoodMenuRowItem>(items);
}   

// ...

@Override
public Filter getFilter() {
return new Filter() {
    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint,
            FilterResults results) {

        if (results.count == 0)
            notifyDataSetInvalidated();
        else {
            rowItems = (List<FoodMenuRowItem>) results.values;
            Menu_List_Item_Adapter.this.notifyDataSetChanged();
        }

    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        FilterResults results = new FilterResults();

        if (constraint == null || constraint.length() == 0) {
            // No filter implemented we return all the list
            results.values = storedRowItems;
            results.count = storedRowItems.size();

        } else { // We perform filtering operation
            List<FoodMenuRowItem> filteredRowItems = new ArrayList<FoodMenuRowItem>();

            rowItems = storedRowItems;
            for (FoodMenuRowItem p : rowItems) {
                if (p.getName()
                        .toUpperCase()
                        .startsWith(constraint.toString().toUpperCase())) {
                    filteredRowItems.add(p);
                }
            }
            results.values = filteredRowItems;
            results.count = filteredRowItems.size();
        }
        return results;
    }
};
}

Upvotes: 3

Related Questions