I have some troubles with my search in listview. I create my custom array adapter with Filter. If the result is correct then it always shows only the first item. When I use base array adapter the result is shown as correct but I need to use the custom adapter. Can you help me? This is my code of the array adapter:
public class ImageAdapter extends ArrayAdapter{
Activity context;
ArrayList<String> original;
ArrayList<String> fitems;
int layoutId;
int textId;
int imageId;
private Filter filter;
ImageAdapter(Activity context, int layoutId, int textId, int imageId, ArrayList<String> data){
super(context,layoutId,data);
this.context = context;
this.original = new ArrayList<>(data);
this.fitems = new ArrayList<>();
this.layoutId = layoutId;
this.textId = textId;
this.imageId = imageId;
}
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
public Object getItem(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater=context.getLayoutInflater();
View row=inflater.inflate(layoutId, null);
TextView label=(TextView)row.findViewById(textId);
label.setText(original.get(position));
ImageView icon=(ImageView)row.findViewById(imageId);
icon.setImageResource(R.drawable.arrow);
return(row);
}
#Override
public Filter getFilter(){
if (filter == null)
filter = new ListFilter();
return filter;
}
private class ListFilter extends Filter{
#Override
protected FilterResults performFiltering(CharSequence constraint){
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
if (prefix == null || prefix.length() == 0){
ArrayList<String> list=new ArrayList<String>(original);
results.values = list;
results.count = list.size();
}
else{
ArrayList<String> values = new ArrayList<String>(original);
ArrayList<String> nlist = new ArrayList<String>();
final int count = values.size();
for (int i=0; i<count; i++){
final String value = values.get(i);
final String valueText = values.get(i).toLowerCase();
if (valueText.startsWith(prefix)){
nlist.add(valueText);
}
else{
final String[] words = valueText.split(" ");
final int wordCount = words.length;
// Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefix)) {
nlist.add(value);
break;
}
}
}
}
results.values = nlist;
results.count = nlist.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
fitems = (ArrayList<String>)results.values;
notifyDataSetChanged();
clear();
for (int i=0; i<fitems.size(); i++){
String str = fitems.get(i);
add(str);
}
notifyDataSetInvalidated();
}
}
}
And I use it:
SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
if(EventForList.size()!=0) {
imAdapter2.getFilter().filter("");
}
else
Toast.makeText(MainActivity.this,"List is empty",Toast.LENGTH_SHORT).show();
}
else {
if(EventForList.size()!=0) {
imAdapter2.getFilter().filter(newText);
}
else
Toast.makeText(MainActivity.this,"List is empty",Toast.LENGTH_SHORT).show();
}
Related
I have a RecylerView which has SearchView widget and list of items containing checkbox and player names. There is no problem when I scroll items and select items checkboxes are selected. But problem arises when ever I search items by there name and then select them, when I try to search another item the previously item gets unchecked.
When i type BAT and list of player with bat are shown then i selected 2 players
Then I remove BAT from searchview and you can see both 2 selected players get deselected
CustomAdapter.java
public class CustomAdapter extends BaseAdapter implements Filterable {
ArrayList<SomeObject> someObjects= new ArrayList<SomeObject>();
ArrayList<String> name=new ArrayList<>();
ArrayList<String> id=new ArrayList<>();
ArrayList<String> role= new ArrayList<>();
ArrayList<String> price= new ArrayList<>();
ArrayList<String> teamName= new ArrayList<>();
CheckBox chk;
int totc=0;
int batc=0;
int maxbat=3;
int bwlc=0;
int maxbal=3;
int allc=0;
int maxall=4;
ValueFilter valueFilter;
int wktc=0;
int maxwkt=1;
Context c;
ArrayList<PlayersPool> players;
ArrayList<PlayersPool> checkdata;
ArrayList<PlayersPool> searchdata;
LayoutInflater inflater;
boolean[] itemChecked;
public CustomAdapter(Context c, ArrayList<PlayersPool> players) {
this.c = c;
this.players = players;
searchdata=players;
itemChecked= new boolean[players.size()];
}
#Override
public int getCount() {
return players.size();
}
#Override
public Object getItem(int position) {
return players.get(position);
}
#Override
public long getItemId(int position)
{
return players.indexOf(getItem(position));
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (inflater==null){
inflater= (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if(convertView==null)
{
convertView=inflater.inflate(R.layout.model,null);
}
final TextView nameP= (TextView) convertView.findViewById(R.id.nameP);
TextView priceP= (TextView) convertView.findViewById(R.id.priceP);
final TextView roleP= (TextView) convertView.findViewById(R.id.roleP);
final TextView team= (TextView)convertView.findViewById(R.id.team_name);
chk= (CheckBox)convertView.findViewById(R.id.cb);
chk.setOnCheckedChangeListener(null);
chk.setFocusable(false);
nameP.setText(players.get(position).getName());
priceP.setText(players.get(position).getPrice());
roleP.setText(players.get(position).getRole());
team.setText(players.get(position).getTeamName());
if (players.get(position).isselected) {
chk.setChecked(true);
} else {
chk.setChecked(false);
}
checkdata= new ArrayList<>();
chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton cb, boolean b) {
if(b) {
players.get(position).isselected = true;
if (players.get(position).getRole().equals("BAT")) {
Toast.makeText(c,"Checked",Toast.LENGTH_SHORT).show();
batc++;
if (batc > 3) {
batc--;
totc--;
chk.setChecked(false);
players.get(position).isselected = false;
}
}
}
else {
players.get(position).isselected = false;
if(players.get(position).getRole().equals("BAT")){
batc--;
}
}
notifyDataSetChanged();
}
});
return convertView;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<PlayersPool> filterList = new ArrayList<PlayersPool>();
for (int i = 0; i < searchdata.size(); i++) {
if ((searchdata.get(i).getRole().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
final PlayersPool play = new PlayersPool();
play.setName(searchdata.get(i).getName());
play.setTeamName(searchdata.get(i).getTeamName());
play.setRole(searchdata.get(i).getRole());
play.setPrice(searchdata.get(i).getPrice());
play.setIsselected(searchdata.get(i).isselected);
filterList.add(play);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = searchdata.size();
results.values = searchdata;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
players = (ArrayList<PlayersPool>) results.values;
notifyDataSetChanged();
}
}
}
You must use loop for this.
if (players.get(position).isselected) {
chk.setChecked(true);
for(PlayersPool item: searchdata){
if(players.get(position).getName().equals(item.getName())){
item.setIsselected(true);
}
}
} else {
chk.setChecked(false);
}
I have a array of strings like :-
public static string[] vehicleArray = string[]{"01:00 India-Malaysia","02:00 India-Singapore","03:00 India-Malaysia"};
Iam passing this array to an AutocompleteTextView like so:-
ArrayAdapter adapter = new ArrayAdapter<System.String> (this, Resource.Layout.rout_row, vehicleArray);
autoCompleteBusStop.Adapter = adapter;
The issue I am facing is, if I type India the items show properly, but if I enter "Malaysia" or "Singapore" the items do not show probably because "-Malaysia" is treated like one word. If i type "-" the items show. How can I search even if I type Malaysia?
You can use Custom adapter for this like
public class CustomAdapter extends BaseAdapter implements Filterable {
private Context context;
private List<String> originalData;
private List<String> filteredData;
private ItemFilter mFilter = new ItemFilter();
public CustomAdapter(List<String> itemList, Context ctx) {
originalData = new ArrayList<String>();
filteredData = new ArrayList<String>();
filteredData = itemList;
originalData = itemList;
context = ctx;
}
#Override
public int getCount() {
return filteredData.size();
}
#Override
public Object getItem(int position) {
return filteredData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(android.R.layout.simple_dropdown_item_1line, null);
}
final TextView text = (TextView) convertView.findViewById(android.R.id.textView);
text.setText(filteredData.get(position));
return convertView;
}
public Filter getFilter() {
return mFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
Filter.FilterResults results = new FilterResults();
final List<String> list = originalData;
int count = list.size();
final ArrayList<String> nlist = new ArrayList<String>(count);
String filterableString;
for (int i = 0; i < count; i++) {
filterableString = list.get(i);
if (filterableString.toLowerCase().contains(filterString)) {
nlist.add(filterableString);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredData = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
}
Suppose I have 4 data in arraylist:
alex
black
chocolate
dark
when I input text to filtering it 'c', the listview displaying "alex", not chocolate.
I tried many times and here is my conclusion about my code:
'whenever i tried to search word that only display 1 result, listview will always show the first array of arraylist'
Please help :(
Here is my adapter:
public class PesertaAdapter extends ArrayAdapter<String> {
public ArrayList<String> items;
public ArrayList<String> filtered;
private int layoutResourceId;
private Context context;
private Filter filter;
public PesertaAdapter(Context context, int layoutResourceId, ArrayList<String> items) {
super(context, layoutResourceId, items);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.filtered = items;
this.items = (ArrayList<String>) items.clone();
}
public static class ViewHolder {
public final TextView tvPeserta;
public final ImageButton mBtnDelete;
public ViewHolder (View view) {
tvPeserta = (TextView) view.findViewById(R.id.text1);
mBtnDelete = (ImageButton) view.findViewById(R.id.btnDel);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder viewHolder = null;
if(row == null){
LayoutInflater inflater = LayoutInflater.from(context);
row = inflater.inflate(layoutResourceId, null);
viewHolder = new ViewHolder(row);
row.setTag(viewHolder);
}
viewHolder = (ViewHolder) row.getTag();
final String s = items.get(position);
viewHolder.tvPeserta.setText(s);
viewHolder.mBtnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "isi: " + s, Toast.LENGTH_SHORT).show();
}
});
return row;
}
#Override
public Filter getFilter() {
if(filter == null){
filter = new PesertaFilter();
}
return filter;
}
private class PesertaFilter extends Filter{
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint == null || constraint.length() == 0){
ArrayList<String> list = new ArrayList<>();
synchronized (this) {
list.addAll(items);
}
results.values = list;
results.count = list.size();
}else{
String prefixString = constraint.toString();
ArrayList<String> filt = new ArrayList<>();
ArrayList<String> lItems = new ArrayList<>();
synchronized (this) {
lItems.addAll(items);
}
for (int i = 0; i < lItems.size(); i++) {
final String value = lItems.get(i);
Log.d("ASD", "VALUE: " + value);
if (value.startsWith(prefixString)) {
Log.d("ASD", "VALUEMATCH: " + value);
filt.add(value);
}
}
results.values = filt;
results.count = filt.size();
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filtered = (ArrayList<String>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
clear();
for(int i = 0; i<results.count; i++){
Log.d("ASD", "FILTERED: " + filtered.get(i));
add(filtered.get(i));
notifyDataSetInvalidated();
}
} else {
notifyDataSetChanged();
clear();
add("Not found");
notifyDataSetInvalidated();
}
}
}
}
When I log the result in array list (variable name='filtered'), I saw the correct result, but it display wrong.
Replace
final String s = items.get(position);
By
final String s = getItem(position);
I am extending the Array Adapter as it follows but I get still the old results can you please tell me what is the problem ?
public class Adaptor extends ArrayAdapter<String> implements Filterable{
private ArrayList<String> items;
public Adaptor(Context context, int textViewResourceId, String[] objects) {
super(context, textViewResourceId, objects);
items = new ArrayList<String>();
for (int i = 0; i < objects.length ; i++)
items.add(objects[i]);
}
#Override
public int getCount() {
return items.size();
}
#Override
public String getItem(int position) {
return items.get(position);
}
#Override
public Filter getFilter() {
Filter myFilter = new Filter(){
#Override
protected FilterResults performFiltering(CharSequence arg0) {
FilterResults rezultate = new FilterResults();
ArrayList<String> chestii = new ArrayList<String>();
for (int i = 0; i < items.size() ; i++)
{
String tmp = items.get(i).toUpperCase();
if (tmp.startsWith(arg0.toString().toUpperCase()))
chestii.add(items.get(i));
}
rezultate.count = chestii.size();
rezultate.values = chestii;
return rezultate;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results != null && results.count > 0)
{
notifyDataSetChanged();
}
else notifyDataSetInvalidated();
}
};
return myFilter;
}
}
Your list contains items from "items" and you don't modify items in it, you have to remove positions from "items" and then call notifyDataSetChange, to restore lately all items you have to save previous items
this is works fine:
/**
* Adapter wrapper to represent list of dialogs
* #author Ryazantsev Dmitry
* #email dilix90#gmail.com 2012
*/
public class FriendsAdapter extends ArrayAdapter<User>
{
private final LayoutInflater inflater;
private final ImageLoader il;
private Context parentContext;
private List<User> mData;
private List<User> mOriginalData;
public SimpleImageLoader sil;
#Override
public void add(User object)
{
if (mOriginalData != null)
mOriginalData.add(object);
else
mData.add(object);
}
#Override
public void remove(User object)
{
if (mOriginalData != null)
mOriginalData.remove(object);
else
mData.remove(object);
}
#Override
public int getCount()
{
return mData.size();
}
#Override
public User getItem(int position)
{
return mData.get(position);
}
#Override
public int getPosition(User item)
{
return mData.indexOf(item);
}
public FriendsAdapter(Context context, int textViewResourceId, List<User> objects)
{
super(context, textViewResourceId, objects);
Log.v("refresh", context + " " + textViewResourceId + " " + objects);
parentContext = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
il = new ImageLoader(context);
mData = objects;
sil = new SimpleImageLoader(context, true, 64);
sil.setOnUiThread(false);
}
/**
* We have a custom view and need to organize it
*/
#Override
public View getView(final int position, View convertView, final ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
convertView = inflater.inflate(R.layout.friends_list_row, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.friendName);
holder.root = convertView.findViewById(R.id.root);
holder.photo = (ImageView) convertView.findViewById(R.id.friendPhoto);
holder.online = (ImageView) convertView.findViewById(R.id.online);
convertView.setTag(holder);
}
else
holder = (ViewHolder) convertView.getTag();
User user = getItem(position);
holder.online.setVisibility(user.isOnline() > 0 ? View.VISIBLE : View.GONE);
if (user != null)
{
holder.name.setText(user.getFIO());
holder.photo.setTag(user.getPhotoUrl());
if (user.getPhotoBitmap() != null)
holder.photo.setImageBitmap(user.getPhotoBitmap());
else
{
holder.photo.setImageResource(R.drawable.contact_nophoto);
sil.displayImageUserAttach(holder.photo, user.getPhotoUrl(), user, null, false, null);
}
}
// parent.setVisibility(position % 2 == 0?View.GONE:View.VISIBLE);
return convertView;
}
private static class ViewHolder
{
public TextView name;
public ImageView photo;
public View root;
public View online;
}
#Override
public Filter getFilter()
{
return new Filter()
{
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
Log.v("filter", "filter finished");
mData = (List<User>) results.values;
if (results.count > 0)
{
notifyDataSetChanged();
}
else
{
notifyDataSetInvalidated();
}
}
#Override
protected FilterResults performFiltering(CharSequence constraint)
{
Log.v("filter", "filter perform");
if (mOriginalData == null)
mOriginalData = new ArrayList<User>(mData);
List<User> result;
FilterResults r = new FilterResults();
if (constraint == null || constraint.length() <= 0)
result = new ArrayList<User>(mOriginalData);
else
{
result = new ArrayList<User>();
for (int i = 0; i < mOriginalData.size(); i++)
if (constraint.length() > 0
&& mOriginalData.get(i).getFIO().toLowerCase()
.contains(constraint.toString().toLowerCase()))
result.add(mOriginalData.get(i));
}
r.values = result;
r.count = result.size();
return r;
}
};
}
}
There was some progress made to the earlier problem. Now there is a new problem. The text in the GridView shows the correct result. However, the images are the same as at the start of the list.
For example: If I search for "Sidd" it displays three results but the photos still start as for the users starting with "A". Attached is a screenshot for clarity.
This is the BaseAdapter code:
public class TagFriendsAdapter extends BaseAdapter implements Filterable {
List<String> arrayListNames;
List<String> mOriginalNames;
List<String> arrayPictures;
List<String> mOriginalPictures;
Activity activity;
String[] fetFriendID;
String[] fetFriendName;
String[] fetFriendPicture;
LayoutInflater inflater = null;
ImageLoader imageLoader;
TagFriendsAdapter(Activity a, String[] stringUID, String[] stringName, String[] stringPicture,
ArrayList<String> arrayName, ArrayList<String> arrayPicture) {
activity = a;
fetFriendID = stringUID;
fetFriendName = stringName;
fetFriendPicture = stringPicture;
this.arrayListNames = arrayName;
this.arrayPictures = arrayPicture;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return arrayListNames.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
vi = inflater.inflate(R.layout.friends_grid_items, null);
ImageView imgProfilePicture = (ImageView)vi.findViewById(R.id.imgProfilePicture);
TextView txtUserName = (TextView)vi.findViewById(R.id.txtUserName);
txtUserName.setText(arrayListNames.get(position));
if (arrayPictures.get(position) != null){
imageLoader.DisplayImage(arrayPictures.get(position), imgProfilePicture);
}
else if (arrayPictures.get(position) == null) {
imgProfilePicture.setVisibility(View.GONE);
}
return vi;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayListNames = (List<String>) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<String> FilteredArrayNames = new ArrayList<String>();
if (mOriginalNames == null && mOriginalPictures == null) {
mOriginalNames = new ArrayList<String>(arrayListNames);
mOriginalPictures = new ArrayList<String>(arrayPictures);
}
if (constraint == null || constraint.length() == 0) {
results.count = mOriginalNames.size();
results.values = mOriginalNames;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalNames.size(); i++) {
String dataNames = mOriginalNames.get(i);
if (dataNames.toLowerCase().startsWith(constraint.toString())) {
FilteredArrayNames.add(dataNames);
}
}
results.count = FilteredArrayNames.size();
System.out.println(results.count);
results.values = FilteredArrayNames;
Log.e("VALUES", results.values.toString());
}
return results;
}
};
return filter;
}
}
And the screenshot:
First refactor your code. Create a class that holds name, picture and other friend data together.
class Friend {
public String name;
public String picture;
... /* more members and access methods*/
};
Then modify your adapter and filtering code accordingly.
FilterResults should contain the ArrayList<Friend>, i.e. a list of Friend objects and not just the names.
In Adapter, replace
List<String> arrayListNames;
List<String> arrayPictures;
with
List<Friend> friendsList;
Change the getView method to access data from the friendsList object list.
After these changes the code will look better and work better.
Update:
Make sure your adapter's getItem method returns a Friend object
public Object getItem(int position) {
return mFriendsList.get(position);
}
Problem is because you are not updating the list of picture names while you filter the array based on edittext input, you also need to update them too,
I have tried to modify your code,check this
public static List<String> temparrayPictures;
public static List<String> temparrayListNames;
public class TagFriendsAdapter extends BaseAdapter implements Filterable {
List<String> arrayListNames;
List<String> arrayPictures;
Activity activity;
String[] fetFriendID;
String[] fetFriendName;
String[] fetFriendPicture;
LayoutInflater inflater = null;
ImageLoader imageLoader;
TagFriendsAdapter(Activity a, String[] stringUID, String[] stringName, String[] stringPicture,
ArrayList<String> arrayName, ArrayList<String> arrayPicture) {
activity = a;
fetFriendID = stringUID;
fetFriendName = stringName;
fetFriendPicture = stringPicture;
this.arrayListNames = arrayName;
this.arrayPictures = arrayPicture;
temparrayPictures = arrayPicture;
temparrayListNames = arrayName;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return temparrayListNames.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
vi = inflater.inflate(R.layout.friends_grid_items, null);
ImageView imgProfilePicture = (ImageView)vi.findViewById(R.id.imgProfilePicture);
TextView txtUserName = (TextView)vi.findViewById(R.id.txtUserName);
txtUserName.setText(temparrayListNames.get(position));
if (temparrayPictures.get(position) != null){
imageLoader.DisplayImage(temparrayPictures.get(position), imgProfilePicture);
}
else if (temparrayPictures.get(position) == null) {
imgProfilePicture.setVisibility(View.GONE);
}
return vi;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
temparrayPictures.clear();
temparrayListNames.clear();
if (temparrayListNames == null && temparrayPictures == null) {
temparrayListNames = new ArrayList<String>(arrayListNames);
temparrayPictures = new ArrayList<String>(arrayPictures);
}
if (constraint == null || constraint.length() == 0) {
results.count = arrayListNames.size();
results.values = arrayListNames;
temparrayPictures = arrayPictures;
temparrayListNames = arrayListNames;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalNames.size(); i++) {
String dataNames = arrayName.get(i);
String picNames = arrayPicture.get(i);
if (dataNames.toLowerCase().startsWith(constraint.toString())) {
temparrayPictures.add(picNames);
temparrayListNames.add(dataNames);
}
}
results.count = temparrayListNames.size();
System.out.println(results.count);
results.values = temparrayListNames;
Log.e("VALUES", results.values.toString());
}
return results;
}
};
return filter;
}
}
Try this:
public class TagFriendsAdapter extends BaseAdapter implements Filterable
{
List<String> arrayListNames;
List<String> mOriginalNames;
List<String> arrayPictures;
List<String> mOriginalPictures;
Activity activity;
String[] fetFriendID;
String[] fetFriendName;
String[] fetFriendPicture;
LayoutInflater inflater = null;
ImageLoader imageLoader;
private Hashtable<String, String> picturesMap = new Hashtable<String, String>();
public void setNamesAndPictures(List<String> arrayListNames, List<String> arrayPictures) {
for(int i = 0; i < arrayListNames.size(); i++){
picturesMap.put(arrayListNames.get(i), arrayPictures.get(i));
}
this.arrayListNames = arrayListNames;
}
TagFriendsAdapter(Activity a, String[] stringUID, String[] stringName, String[] stringPicture,
ArrayList<String> arrayName, ArrayList<String> arrayPicture) {
activity = a;
fetFriendID = stringUID;
fetFriendName = stringName;
fetFriendPicture = stringPicture;
this.arrayListNames = arrayName;
this.arrayPictures = arrayPicture;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
#Override
public int getCount() {
return arrayListNames.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
vi = inflater.inflate(R.layout.friends_grid_items, null);
ImageView imgProfilePicture = (ImageView) vi.findViewById(R.id.imgProfilePicture);
TextView txtUserName = (TextView) vi.findViewById(R.id.txtUserName);
txtUserName.setText(arrayListNames.get(position));
String url = picturesMap.get(arrayListNames.get(position));
if(url != null){
imageLoader.DisplayImage(url, imgProfilePicture);
}
else if(arrayPictures.get(position) == null){
imgProfilePicture.setVisibility(View.GONE);
}
return vi;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayListNames = (List<String>) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<String> FilteredArrayNames = new ArrayList<String>();
if(mOriginalNames == null && mOriginalPictures == null){
mOriginalNames = new ArrayList<String>(arrayListNames);
mOriginalPictures = new ArrayList<String>(arrayPictures);
}
if(constraint == null || constraint.length() == 0){
results.count = mOriginalNames.size();
results.values = mOriginalNames;
}
else{
constraint = constraint.toString().toLowerCase();
for(int i = 0; i < mOriginalNames.size(); i++){
String dataNames = mOriginalNames.get(i);
if(dataNames.toLowerCase().startsWith(constraint.toString())){
FilteredArrayNames.add(dataNames);
}
}
results.count = FilteredArrayNames.size();
System.out.println(results.count);
results.values = FilteredArrayNames;
Log.e("VALUES", results.values.toString());
}
return results;
}
};
return filter;
}
}
#MKJParekh did a great job!To sum up his implementation:
Declare a temporary List of objects at the beginning of the class that reflect the incoming data used for each item (1 object per item).
In the performFiltering()set the condition for nulls and empty strings, and also if the constraint matches the string value of the corresponding object, then add the object to the temp List. That way you have only a "filtered" list of objects.
Use data from your temp list, rather than your data source (as you normally would), for methods such as getCount(), getItem(), and getView(). Otherwise, you'll just be loading ALL the items everytime, since untimately notifyDataSetChanged() will be called after each filtering.