Nitish
Nitish

Reputation: 3155

Android: Results of filtering custom adapter are not reflecting in the UI

In my app, I am fetching data from web server and showing the data in a list view. The adapter for my list view contains both image and text. Now,I want to filter list view. For this, I had implemented Filterable interface in my custom adapter. But, it is not giving any result. I searched alot but couldn'tcome toany result. Here's my code:

MainActivity

Runnable r = new Runnable() 
        {
            @Override
            public void run() 
            { 
                listMainMenu.setAdapter(mMenuAdapter);
                listMainMenu.setTextFilterEnabled(true);
                mMenuAdapter.notifyDataSetChanged();
                pd.dismiss();
                updateUI = false;
            }//run
        };

Text Watcher class

_txtAutoSearch.addTextChangedListener(filterTextWatcher);

private TextWatcher filterTextWatcher = new TextWatcher() {
    public void afterTextChanged(Editable s) {
        Log.v(TAG+" filtertextwatcher", "afterTextChanged");
    }//afterTextChanged

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        Log.v(TAG+" filtertextwatcher", "beforeTextChanged");
    }//beforeTextChanged

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.v(TAG+" filtertextwatcher", "onTextChanged");
        ((Filterable) listMainMenu.getAdapter()).getFilter().filter(s.toString());
    }//onTextChanged
};

My custom adapter:

    public class MainMenuAdapter extends BaseAdapter implements Filterable {
    Context ctx;
    ArrayList<MainCategoryDAO> mainCatDAOList;
    public static final String TAG = "MainMenuAdapter";
    ArrayList<MainCategoryDAO> arrayList;

    public MainMenuAdapter(Context ctx, ArrayList<MainCategoryDAO> mainCatDAOList) {
        this.ctx = ctx;
        this.mainCatDAOList = mainCatDAOList;
    }//Constructor

    public int getCount() {
        return mainCatDAOList.size();
    }//getCount

    public Object getItem(int position) {
        return mainCatDAOList.get(position);
    }//getItem

    public long getItemId(int position) {
        return 0;
    }//getItemId

    class ViewHolder {
        ImageView imgCategoryIcon;
        TextView txtCategoryName;
    }//ViewHolder

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_menu_adapter, null);
            holder = new ViewHolder();
            holder.imgCategoryIcon = (ImageView)convertView.findViewById(R.id.imgCategoryIcon);
            holder.txtCategoryName = (TextView)convertView.findViewById(R.id.txtCategoryName);
            convertView.setTag(holder);
        }//if
        else {
            holder = (ViewHolder) convertView.getTag();
        }//else
        Typeface cat_nameTF = Typeface.createFromAsset(ctx.getAssets(), "fonts/arial.ttf");
        Log.v(TAG, "category name "+ mainCatDAOList.get(position).getCategory_name());
        Log.v(TAG, "category icon "+ mainCatDAOList.get(position).getCategory_icon());
        BitmapManager.INSTANCE.loadBitmap(mainCatDAOList.get(position).getCategory_icon(), holder.imgCategoryIcon, 50, 50);
        holder.txtCategoryName.setTypeface(cat_nameTF);
        holder.txtCategoryName.setText(mainCatDAOList.get(position).getCategory_name());
        Log.v(TAG, "text view category name "+ holder.txtCategoryName.getText());
        return convertView;
    }//getView

    @Override
public Filter getFilter() 
{
    Filter mFilter = new Filter() 
    {

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) 
        {
            Log.v(TAG+" getFilter", "publishResults called");
            arrayList = (ArrayList<MainCategoryDAO>) results.values;
            Log.v(TAG+" getFilter", "publishResults arrayList size "+arrayList.size());
            for(int i = 0; i < arrayList.size(); i++)
            {
                Log.v(TAG+" getFilter filtered name", " "+arrayList.get(i).getCategory_name());
            }//for
            notifyDataSetChanged();
        }//publishResults

        @Override
        protected FilterResults performFiltering(CharSequence constraint) 
        {
            Log.v(TAG+" getFilter", "performFiltering called");
            FilterResults results = new FilterResults();
            ArrayList<MainCategoryDAO> FilteredArrList = new ArrayList<MainCategoryDAO>();

            if (constraint == null || constraint.length() == 0) 
            {
                Log.v(TAG+" getFilter", "if, constraint.length null or 0");
                results.count = mainCatDAOList.size();
                results.values = mainCatDAOList;
            }//if 
            else 
            {
                Log.v(TAG+" getFilter", "else, constraint.length not 0");
                constraint = constraint.toString();
                Log.v(TAG+" getFilter", "else, constraint = "+constraint);
                for (int i = 0; i < mainCatDAOList.size(); i++) 
                {
                    Log.v(TAG+" getFilter", "for loop, constraint.length not null or 0");
                    String data = mainCatDAOList.get(i).getCategory_name();
                    Log.v(TAG+" getFilter", "else, data to check "+data);
                    if (data.toLowerCase().startsWith(constraint.toString()))   
                    {
                        Log.v(TAG+" getFilter", "if in for loop, constraint.length not null or 0");
                        FilteredArrList.add(mainCatDAOList.get(i));
                    }//if
                }//for
                results.count = FilteredArrList.size();
                results.values = FilteredArrList;
            }//else
            return results;
        }//performFiltering
    };
    return mFilter;
}//getFilter
}//MainMenuAdapter

Upon testing, I found that it is filtering the result but, changes are not reflecting in listview. I even tried setting listview.setTextFilterEnabled() to true, but it also didn't worked. While on my logcat, I can see the filtered values. but not getting why the same is not reflecting in the UI.

Upvotes: 1

Views: 6343

Answers (2)

user
user

Reputation: 87074

It's normal that you don't see any UI changes, because you aren't updating the right list of data after the filtering. Your MainMenuAdapter is based on the mainCatDAOList list of data, but in the publishResults method where the adapter's data should be refreshed you do:

arrayList = (ArrayList<MainCategoryDAO>) results.values;
notifyDataSetChanged();

As you can see you're updating the arrayList with the filtered values instead of mainCatDAOList so the adapter doesn't see any changes. So your code should be:

protected void publishResults(CharSequence constraint,
            FilterResults results) {
        Log.v(TAG+" getFilter", "publishResults called");
        mainCatDAOList = (ArrayList<MainCategoryDAO>) results.values;
        Log.v(TAG+" getFilter", "publishResults arrayList size "+arrayList.size());
        for(int i = 0; i < arrayList.size(); i++)
        {
            Log.v(TAG+" getFilter filtered name", " "+arrayList.get(i).getCategory_name());
        }//for
        notifyDataSetChanged();
    }

Also you should have a copy of the initial list of data to be used for filtering, otherwise you'll not be able to return to the full set of values.

Upvotes: 4

Thirumalvalavan
Thirumalvalavan

Reputation: 2768

Do you add

Adapter.notifyDataSetChanged();

in your code? can you show your main activity code? I will help us.

Upvotes: 1

Related Questions