Reputation: 3155
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
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
Reputation: 2768
Do you add
Adapter.notifyDataSetChanged();
in your code? can you show your main activity code? I will help us.
Upvotes: 1