Android Searchview Filter Listview

Android SearchView Filter ListView

Place this inside your adapter:

@Override
public Filter getFilter(){
return new Filter(){

@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();

if (constraint != null && constraint.toString().length() > 0) {
List<String> founded = new ArrayList<String>();
for(YourListItemType item: origData){
if(item.toString().toLowerCase().contains(constraint)){
founded.add(item);
}
}

result.values = founded;
result.count = founded.size();
}else {
result.values = origData;
result.count = origData.size();
}
return result;

}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
for (String item : (List<String>) results.values) {
add(item);
}
notifyDataSetChanged();

}

}
}

And this inside constructor of your adapter

public MyAdapter(Context context, int layoutResourceId, String[] places) {
super(context, layoutResourceId, data);
this.context = context;

this.data = Arrays.asList(places);
this.origData = new ArrayList<String>(this.data);

}

Android SearchView Filter for List View

in your onQueryTextChange(String Text) method of Listener use:
adapter.getFilter().filter(Text.toString()); and implement your filter in your BaseAdapter class.
here is the sample code:

 @Override
public Filter getFilter()
{
return filter;
}

private GameFilter filter;

private class GameFilter extends Filter
{
public GameFilter() { }
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults oReturn = new FilterResults();
ArrayList<ItemDetails> results = new ArrayList<ItemDetails>();
if (orig == null)
orig = itemDetailsrrayList;
if (constraint != null)
{
if (orig != null && orig.size() > 0) {
for (ItemDetails g : orig) {
if (g.getName().toLowerCase().contains(constraint.toString().toLowerCase()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
itemDetailsrrayList = (ArrayList<ItemDetails>)results.values;
notifyDataSetChanged();
}
}

SearchView filter ListView

Before you return your FilterResults, you must specify its value AND count. Currently you are just specifying the value like so...

results.values = filteredResults;

Under that line, before you return results in your performFiltering(...) method, add this line...

results.count = filteredResults.size();

EDIT: An fully working adapter with filter from a project i've done

class ContactsAdapter extends BaseAdapter implements Filterable {

private List<Contact> mData;
private List<Contact> database;
private LayoutInflater mInflater;
private Context context;
static boolean inMarkMode = false;

ContactsAdapter(List<Contact> mData, List<Contact> database, Context context) {
this.mData = mData;
this.context = context;
this.database = database;
mInflater = LayoutInflater.from(context);
}

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

/**
* Modifies the way a contact is shown in its adapter depending on
* displayChoice shared preference
*
* @param position
* of the contact in its listview
* @return <code>String</code> to display
*/
@Override
public String getItem(int position) {
switch (context.getSharedPreferences("settings",
HomeScreenActivity.MODE_PRIVATE).getInt("displayChoice", -1)) {
case 1:
return mData.get(position).getLastName() + " "
+ mData.get(position).getFirstName();
case 2:
return mData.get(position).getFirstName() + " "
+ mData.get(position).getMobileNumber();
case 3:
return mData.get(position).getLastName() + " "
+ mData.get(position).getMobileNumber();
default:
return mData.get(position).getFirstName() + " "
+ mData.get(position).getLastName();
}
}

@Override
public long getItemId(int position) {
return position;
}

/**
* Modifies the view shown in HomeScreenActivity depending on whether the
* user has entered mark mode or not
*
* @return <code>View</code> to display
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {

CheckedTextView result = null;
TextView normalResult = null;
final String contactRow = getItem(position);

if (inMarkMode) {// if user is in markMode, use the mark layout
if (convertView == null) {
result = (CheckedTextView) mInflater.inflate(
R.layout.home_screen_contacts_mark_view, parent, false);
} else {
result = (CheckedTextView) convertView;
}
result.setText(contactRow);
result.setBackgroundResource(R.drawable.list_selector);
} else { // if user NOT in markmode, use normal contacts view layout
if (convertView == null) {
normalResult = (TextView) mInflater.inflate(
R.layout.home_screen_contacts_view, parent, false);
} else {
normalResult = (TextView) convertView;
}
normalResult.setText(contactRow);
normalResult.setBackgroundResource(R.drawable.list_selector);
}

if (inMarkMode) {
return result;
} else {
return normalResult;
}
}

int getItemIdAtPosition(int position) {
return mData.get(position).getID();
}

@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
// If there's nothing to filter on, return the original data for
// your list
if (charSequence == null || charSequence.length() == 0) {
results.values = database;
results.count = database.size();
} else {
List<Contact> filterResultsData = new ArrayList<Contact>();

// if search details is 0, search fullName, else, search
// all details
if (HomeScreenActivity.searchAllDetails == 0) {
for (Contact c : database) {
if (c.getFullName().toLowerCase(Locale.ENGLISH)
.contains(charSequence)) {
filterResultsData.add(c);
}
}
} else {
for (Contact c : database) {
if (c.getAllDetailsForSearch()
.toLowerCase(Locale.ENGLISH)
.contains(charSequence)) {
filterResultsData.add(c);
}
}
}

results.values = filterResultsData;
results.count = filterResultsData.size();
}

return results;
}

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence charSequence,
FilterResults filterResults) {
// set the data to the filter results and notifyDataSetChanged()
mData = (List<Contact>) filterResults.values;
notifyDataSetChanged();
}
};
}
}

Search filter in listview for array of strings with android SearchView

For comparing the strings partially you can use the indexOf function like below.

if(dataNames.getGenre().toLowerCase().indexOf(constraint)>-1){
//add to your list
filteredList.add(dataNames);
} else{
//doesn't satisfy the filter condition.
}

Another thing noticed is that if your getGenre() is a List you don't need to add all the string together and check the filter condition you can do it like below.
You can split the comma separated value to a list string and loop through it and check filter.

List<String> filterList = Arrays.asList(constraint.split(","))
bool hasAdded;
for (String str : dataNames.getGenre())
{
for (String filter : filterList) {
if(str.toLowerCase().indexOf(filter.trim().toLowerCase())>-1){
//add to your list
filteredList.add(dataNames);
hasAdded = true;
break;
}
if(hasAdded) break;
}
}

Also you can change the for loop with foreach for looping dataListFilter.

Android Searchview filtering wrong on item click with ListView

First of all use ArrayList instead of array to initialize ArrayAdapter

ArrayList<String> name = new ArrayList<>(Arrays.asList(
"General Science", "Social Science", "Maths", "English", "Politics", "IT"
));

Then use below code to find out correct position of your filtered data

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

int actualPosition = name.indexOf(adapter.getItem(position));

Intent ij = new Intent(getApplicationContext(), PdfView.class);
ij.putExtra("furl", "fl/" + file[actualPosition]);
ij.putExtra("pagenm", pagenum[actualPosition]);
startActivity(ij);
}

How to apply search filter using startsWith on a simple listview in android

You need to use a customized adapter instead of the default one, and override the getFilter() to filter the list with the String's startsWith() method:

Adapter:

public class StartsWithArrayAdapter extends ArrayAdapter<String> implements Filterable {

private final List<String> mList = new ArrayList<>();
private List<String> mFilteredList = new ArrayList<>();

public StartsWithArrayAdapter(Context context, int textViewResourceId, ArrayList<String> list) {
super(context, textViewResourceId, list);
this.mList.addAll(list);
this.mFilteredList.addAll(list);
}

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

@NonNull
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = mList;
} else {
List<String> filteredList = new ArrayList<>();
for (String listItem : mList) {
if (listItem.toLowerCase().startsWith(charString.toLowerCase())) {
filteredList.add(listItem);
}
}
mFilteredList = filteredList;
}

FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}

@Override
@SuppressWarnings("unchecked")
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilteredList = (ArrayList<String>) filterResults.values;
clear();
addAll(mFilteredList);
notifyDataSetChanged();
}
};

}

}

Usage in your code:

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

StartsWithArrayAdapter adapterListOfWord;

// rest of code

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// omitted code

adapterListOfWord = new StartsWithArrayAdapter(this, android.R.layout.simple_list_item_1, mSource);

// rest of code

}
}


Related Topics



Leave a reply



Submit