I have referred to this , this also and this one too. No where I am finding the solution of my problem. On typing in edit text No filtering is there and list view remains as it is Here is the code:
MainActivity.java
public class MainActivity extends AppCompatActivity implements OnItemClickListener {
public static final String[] titles = new String[] { "H C Verma",
"P Bahadur", "I E Irodov", "M L Khanna",
"O P Tondon", "Morrison & Boyd", "Halliday Resnick",
"R D Sharma", "S L Loney", "Hall and Knight", "Krotov", "I A Maron" };
public EditText search;
CustomAdapter adapter;
public static final String[] descriptions = new String[] {
"Physics",
"Chemistry",
"Physics",
"Mathematics",
"Chemistry",
"Chemistry",
"Physics",
"Mathematics",
"Mathematics",
"Chemistry",
"Physics",
"Mathematics"
};
public static final Integer[] images = { R.drawable.hcv,
R.drawable.bahadur, R.drawable.irodov, R.drawable.mlkhanna,
R.drawable.tondon, R.drawable.boyd, R.drawable.resnick, R.drawable.sharma,
R.drawable.loney, R.drawable.knight, R.drawable.krotov, R.drawable.maron};
public static final String[] pub = new String[]{"Bharti Bhavan", "G R Bathla Publications", "Arihant",
"Jai Prakash Nath", "G R Bathla Publications", "Pearson Publications",
"Wiley Publications", "Dhanpat Rai Publications","Classic Texts series","Classic Texts series","G K Publications","G K Publications"};
ListView listView;
List<RowItem> rowItems;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
search = (EditText)findViewById(R.id.inputSearch);
rowItems = new ArrayList<>();
for (int i = 0; i < titles.length; i++) {
RowItem item = new RowItem(images[i], titles[i], descriptions[i], pub[i]);
rowItems.add(item);
}
listView = (ListView) findViewById(R.id.list);
adapter = new CustomAdapter(this, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
listView.setTextFilterEnabled(true);
search.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"]");
adapter.getFilter().filter(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Item " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.show();
}
}
CustomAdapter.java
public class CustomAdapter extends BaseAdapter implements Filterable{
List<RowItem> filteredData;
Context context;
List<RowItem> rowItems;
CustomFilter filter;
public CustomAdapter(Context context, List<RowItem> items) {
this.context = context;
this.rowItems = items;
this.filteredData = items;
}
@Override
public int getCount() {
return filteredData.size();
}
@Override
public Object getItem(int position) {
return filteredData.get(position);
}
@Override
public long getItemId(int position) {
return rowItems.indexOf(getItem(position));
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtDesc;
TextView pubname;
}
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.list_item, parent, false);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.pubname = (TextView) convertView.findViewById(R.id.pub);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowItem rowItem = (RowItem) getItem(position);
holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
holder.pubname.setText(rowItem.getPub());
holder.imageView.setImageResource(rowItem.getImageId());
return convertView;
}
public Filter getFilter() {
if(filter == null)
{
filter=new CustomFilter();
}
return filter;}
class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
//CONSTARINT TO UPPER
constraint = constraint.toString().toUpperCase();
ArrayList<RowItem> filters = new ArrayList<RowItem>();
//get specific items
for (int i = 0; i < filteredData.size(); i++) {
if (filteredData.get(i).getTitle().toUpperCase().contains(constraint)) {
RowItem p = new RowItem(filteredData.get(i).getImageId(), filteredData.get(i).getTitle(), filteredData.get(i).getDesc(), filteredData.get(i).getPub());
filters.add(p);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count = filteredData.size();
results.values = filteredData;
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
rowItems = (ArrayList<RowItem>) results.values;
notifyDataSetChanged();
}
}
}}
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="35dp"
android:orientation="vertical" >
<EditText android:id="@+id/inputSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="45dp"
android:hint="Search Books.."
android:inputType="textVisiblePassword"/>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:padding="20dip"
android:listSelector="@drawable/list_selector"
/>
</LinearLayout>
Please help me out.
using ArrayAdapter
public class CustomAdapter extends ArrayAdapter<RowItem> implements Filterable{
List<RowItem> filteredData;
Context context;
List<RowItem> rowItems;
CustomFilter filter;
public CustomAdapter(Context context, List<RowItem> items) {
super(context, R.layout.list_item);
this.context = context;
this.rowItems = items;
this.filteredData = items;
}
/* @Override
public int getCount() {
return filteredData.size();
}
@Override
public Object getItem(int position) {
return filteredData.get(position);
}
@Override
public long getItemId(int position) {
return rowItems.indexOf(getItem(position));
}*/
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtDesc;
TextView pubname;
}
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.list_item, parent, false);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.pubname = (TextView) convertView.findViewById(R.id.pub);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowItem rowItem = (RowItem) getItem(position);
holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
holder.pubname.setText(rowItem.getPub());
holder.imageView.setImageResource(rowItem.getImageId());
return convertView;
}
public Filter getFilter() {
if(filter == null)
{
filter=new CustomFilter();
}
return filter;}
class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
//CONSTARINT TO UPPER
constraint = constraint.toString().toUpperCase();
ArrayList<RowItem> filters = new ArrayList<RowItem>();
//get specific items
for (int i = 0; i < filteredData.size(); i++) {
if (filteredData.get(i).getTitle().toUpperCase().contains(constraint)) {
RowItem p = new RowItem(filteredData.get(i).getImageId(), filteredData.get(i).getTitle(), filteredData.get(i).getDesc(), filteredData.get(i).getPub());
filters.add(p);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count = filteredData.size();
results.values = filteredData;
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
rowItems = (ArrayList<RowItem>) results.values;
notifyDataSetChanged();
}
}
}
Ok so! The two silly mistakes done in the code is: In CustomAdapter.java which is extending base class replace
rowItems = (ArrayList<RowItem>) results.values;
with
filteredData = (ArrayList<RowItem>) results.values;
and since on erasing the text entered in edit text also leads to textchange function being called and hence if filteredData is again searched than it will search only out of previously filtered data, so add
filteredData = rowItems;
just before
FilterResults results = new FilterResults();
Thank you.