Everything in the code below works except the when you try and search for a value, the application just doesnt respond to when you type letters into the searchview which should be filtering the gridview.
Cheers, Kripzy
Main Activity:
String[] Champions = {"Aatrox", "Ahri", "Akali"};
int[] Champimgs = {R.drawable.aatrox_square_0, R.drawable.ahri_square_0, R.drawable.akali_square_0};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gv = (GridView) findViewById(R.id.gridView);
sv = (SearchView) findViewById(R.id.searchView);
final Adapter adapter=new Adapter(this,this.getChampions());
gv.setAdapter(adapter);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String arg0) {
return false;
}
#Override
public boolean onQueryTextChange(String query) {
adapter.getFilter().filter(query);
return false;
}
});
}
private ArrayList<Champions> getChampions()
{
ArrayList<Champions> champions = new ArrayList<Champions>();
Champions p;
for (int i = 0; i < Champions.length; i++)
{
p = new Champions(Champions[i], Champimgs[i]);
champions.add(p);
}
return champions;
}
}
Champions
public Champions(String Champion, int Champimg) {
this.Champimg=Champimg;
this.Champion=Champion;}
public String getChampion() {
return Champion;
}
public int getChampimg() {
return Champimg;
}
public void setChampion(String champion) {
Champion = champion;
}
public void setChampimg(int champimg) {
Champimg = champimg;
}
}
Adapter
public Adapter(Context ctx, ArrayList<Champions> Champion){
this.c=ctx;
this.Champion=Champion;
this.filterlist=Champion;
}
#Override
public int getCount() {
return Champion.size();
}
#Override
public Object getItem(int position) {
return Champion.get(position);
}
#Override
public long getItemId(int position) {
return Champion.indexOf(getItem(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.model, null);
}
TextView nameTxt = (TextView) convertView.findViewById(R.id.textView);
ImageView img = (ImageView) convertView.findViewById(R.id.imageView);
nameTxt.setText(Champion.get(position).getChampion());
img.setImageResource(Champion.get(position).getChampimg());
return convertView;
}
#Override
public Filter getFilter() {
if (filter == null)
{
filter=new CustomFiler();
}
return filter;
}
class CustomFiler extends Filter
{
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if (constraint != null && constraint.length() > 0)
{
constraint=constraint.toString().toUpperCase();
ArrayList<Champions> filters = new ArrayList<Champions>();
for(int i = 0;i<filterlist.size();i++){
if (filterlist.get(i).getChampion().toUpperCase().contains(constraint));
{
Champions p= new Champions (filterlist.get(i).getChampion(),filterlist.get(i).getChampimg());
filters.add(p);
}
}
results.count=filters.size();
results.values=filters;
}else{
results.count=filterlist.size();
results.values=filterlist;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Champion = (ArrayList<Champions>) results.values;
notifyDataSetChanged();
}
}
}
you have a little bug in this line:
if (filterlist.get(i).getChampion().toUpperCase().contains(constraint));
the bug is ; symbol in the end of if statement. It makes code below if run each time, therefore filter doesn't work. Just remove ; symbol after if statement
Related
I nearly achieved what I wanted but 1 thing is still missing. I have a recyclerview and each item has it's own recyclerview. But in the beginning, every item's own recyclerview isn't shown. It expands as soon as you press the button.
But I also want to expand it, when I start filtering the recyclerview using the Searchbar.
That's my Adapter:
public class SchrankAdapter extends RecyclerView.Adapter<SchrankAdapter.ViewHolder> implements Filterable {
private Context context;
ArrayList<CategoryName> categoryTopic = new ArrayList<>();
ArrayList<CategoryName> categoryTopicFull;
public SchrankAdapter(Context context, ArrayList<CategoryName> categoryTopic){
this.context = context;
this.categoryTopic = categoryTopic;
categoryTopicFull = new ArrayList<>(categoryTopic);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_schrank, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
CategoryName parentItem = categoryTopic.get(position);
holder.categoryName.setText(parentItem.categoryName);
setCatItemRecycler(holder.childRecView, categoryTopic.get(position).getChildViewList());
holder.btFolderPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.btFolderMinus.setVisibility(View.VISIBLE);
holder.childView.setVisibility(View.VISIBLE);
holder.btFolderPlus.setVisibility(View.GONE);
}
});
holder.btFolderMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.btFolderPlus.setVisibility(View.VISIBLE);
holder.btFolderMinus.setVisibility(View.GONE);
holder.childView.setVisibility(View.GONE);
}
});
}
#Override
public int getItemCount() {
return categoryTopic.size();
}
private void setCatItemRecycler(RecyclerView recyclerView, ArrayList<CategoryChild> categoryChildrenList) {
SchrankChildAdapter childAdapter = new SchrankChildAdapter(context, categoryChildrenList);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(childAdapter);
}
#Override
public Filter getFilter() {
return filter;
}
private Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<CategoryName> filteredList = new ArrayList<>();
ArrayList<CategoryChild> filteredSubList = new ArrayList<>();
boolean containsSubItems = false;
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(categoryTopicFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (CategoryName item: categoryTopicFull) {
for(CategoryChild subItem: item.getChildViewList()) {
if(subItem.getCategoryAttribute().toLowerCase().contains(filterPattern)) {
filteredSubList.add(subItem);
containsSubItems = true;
}
}
if(containsSubItems) {
filteredList.add(new CategoryName(item.getCategoryName(), filteredSubList));
containsSubItems = false;
filteredSubList = new ArrayList<>();
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
categoryTopic.clear();
categoryTopic.addAll((ArrayList) results.values);
notifyDataSetChanged();
}
};
public class ViewHolder extends RecyclerView.ViewHolder{
TextView categoryName;
RelativeLayout childView;
RecyclerView childRecView;
Button btFolderPlus, btFolderMinus;
public ViewHolder(#NonNull View itemView) {
super(itemView);
categoryName = itemView.findViewById(R.id.categoryName);
childView = itemView.findViewById(R.id.childView);
childRecView = itemView.findViewById(R.id.childRecView);
btFolderPlus = itemView.findViewById(R.id.btFolderPlus);
btFolderMinus = itemView.findViewById(R.id.btFolderMinus);
}
}
}
That's my SearchView in the activity:
SearchView searchView = findViewById(R.id.searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
schrankAdapter.getFilter().filter(newText);
return false;
}
});
The variable childView is responsible for the subItems. I want to set it's Visibility to VISIBLE whenever I enter something in the searchbar.
It's all working, I just want to improve my current program.
UPDATE:
Ok, I found a solution for my problem.
I created a boolean which is set to false from the beginning.
I added this code to onBindViewHolder method:
if(isSearching) {
holder.btFolderMinus.setVisibility(View.VISIBLE);
holder.childView.setVisibility(View.VISIBLE);
holder.btFolderPlus.setVisibility(View.GONE);
}
else if(!isSearching) {
holder.btFolderPlus.setVisibility(View.VISIBLE);
holder.btFolderMinus.setVisibility(View.GONE);
holder.childView.setVisibility(View.GONE);
}
And I edited my Filter:
private Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<CategoryName> filteredList = new ArrayList<>();
ArrayList<CategoryChild> filteredSubList = new ArrayList<>();
boolean containsSubItems = false;
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(categoryTopicFull);
isSearching = false;
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (CategoryName item: categoryTopicFull) {
for(CategoryChild subItem: item.getChildViewList()) {
if(subItem.getCategoryAttribute().toLowerCase().contains(filterPattern)) {
filteredSubList.add(subItem);
containsSubItems = true;
}
}
if(containsSubItems) {
filteredList.add(new CategoryName(item.getCategoryName(), filteredSubList));
containsSubItems = false;
filteredSubList = new ArrayList<>();
}
}
isSearching = true;
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
Maybe someone will search for this solution one-day.
I have written code for an app that is designed to read XML and populate a listview with the data read. The data is stored in a containing class. I've created an adapter class as well as a custom filter. For some reason, when I type inside my searchView, nothing comes up! I've looked all over youtube/google for a few days and cannot find anything! please help!
private class ArticleAdapter extends ArrayAdapter<Article> implements Filterable {
private List<Article> completeList = new ArrayList<>(articles);
public ArticleAdapter(Context ctx) {
super(ctx, 0);
}
#NonNull
#Override
public Filter getFilter() {
return titleFilter;
}
public int getCount() {
return articles.size();
}
public Article getItem(int position) {
return articles.get(position);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.title_layout, parent, false);
}
TextView articleTitle = convertView.findViewById(R.id.titleId);
Article article = getItem(position);
if (article != null) {
articleTitle.setText(getItem(position).title);
}
return convertView;
}
Filter titleFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<Article> suggestions = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
suggestions.addAll(completeList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Article title : completeList) {
if (title.getTitle().toLowerCase().contains(filterPattern)) {
suggestions.add(title);
}
}
}
results.values = suggestions;
results.count = suggestions.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
addAll((List) results.values);
notifyDataSetChanged();
}
#Override
public CharSequence convertResultToString(Object resultValue) {
return ((Article) resultValue).getTitle();
}
};
/* public long getItemId(int position) {
return getItem(position).id;
}
*/
}
}
And this is the onCreateOptionsMenu method from my ArticleList class (main class)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_search, menu);
item = menu.findItem(R.id.menuSearch);
searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (articles.isEmpty()) {
}
adapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
I had a list of customers where I had to search a customer by their name.So here is the code.I hope it helps. :)
//Defined this two list global
private List customerList = new ArrayList<>();
private List searchCustomerList = new ArrayList<>();
In onCreate() I call this method : addTextListener();
private void addTextListener()
{
try {
searchBar.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().toLowerCase();
searchCustomerList.clear();
for (int i = 0; i < customerList.size(); i++) {
if (customerList.get(i) != null) {
String text = customerList.get(i).getCustomerName().toLowerCase();
if (text.toString().contains(query)) {
searchCustomerList.add(customerList.get(i));
}
}
}
Log.d("filterflower", "size: " + searchCustomerList.size());
customerListAdapter.updateList(searchCustomerList); // data set changed
}
});
}catch (Exception e){
e.printStackTrace();
}
}
//Here is the updateList Method in my recycler adapter
public void updateList(List<CustomerListDataModel> searchCustomerList) {
customerList = searchCustomerList;
notifyDataSetChanged();
}
I have one custom list view adapter loading contact list. When I open app, contacts are loading perfectly , but once I came back after scrolling to Preference Fragment, listview is empty. Though Data is collected by calling Inner class LoadContact but nothing in listview. There are three fragments. pls guide.
Code for Fragment (tab1). If u see I added adapter initialization in oncreatview as otherwise on back tab I m getting Null point exception. m I did correct here?
public class Requestor extends Fragment {
EditText targetdevice;
ListView recentlist;
List<String> recentlistarray = new ArrayList<>();
ArrayAdapter arrayAdapter;
Dialog dialog;
String targetmobile, requesttype;
private TextView tex1, remotelocation;
int deviceid;
LinearLayout contactlayout;
RadioButton radiorecent, radiocontact;
ArrayList<ContactListSelectUser> contactListSelectUsers;
List<ContactListSelectUser> temp;
// Contact List
ListView listView;
// Cursor to load contacts list
Cursor phones, email;
// Pop up
ContentResolver resolver;
SearchView search;
ContactListAdapter adapter;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
LoadContact loadContact = new LoadContact();
loadContact.execute();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) throws NullPointerException{
View view = inflater.inflate(R.layout.autolocationrequester, container, false);
targetdevice = (EditText) view.findViewById(R.id.targetdevice);
recentlist = (ListView) view.findViewById(R.id.targetlist);
remotelocation = (TextView) view.findViewById(R.id.remotelocationreq);
tex1 = (TextView) view.findViewById(R.id.tex1);
requesttype = "Location";
radiorecent = (RadioButton) view.findViewById(R.id.radiorecent);
radiocontact = (RadioButton) view.findViewById(R.id.radiocontact);
contactlayout = (LinearLayout) view.findViewById(R.id.contactlayout);
tex1 = (TextView) view.findViewById(R.id.tex1);
recentlist.setVisibility(View.GONE);
contactlayout.setVisibility(View.GONE);
tex1.setVisibility(View.GONE);
contactListSelectUsers = new ArrayList<ContactListSelectUser>();
resolver = getActivity().getApplicationContext().getContentResolver();
listView = (ListView) view.findViewById(R.id.contacts_list);
adapter = new ContactListAdapter(contactListSelectUsers, getActivity().getApplicationContext());
phones = getActivity().getApplicationContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
LoadContact loadContact = new LoadContact();
loadContact.execute();
search = (SearchView) view.findViewById(R.id.searchView);
//*** setOnQueryTextListener ***
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
adapter.filter(newText);
return false;
}
});
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
deviceid = Integer.parseInt(sharedPreferences.getString("deviceid", ""));
remotelocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
arrayAdapter = new ArrayAdapter(getActivity().getApplicationContext(), android.R.layout.simple_list_item_1, recentlistarray);
recentlist.setAdapter(arrayAdapter);
targetmobile = targetdevice.getText().toString();
new sendreqloc().execute();
targetdevice.setText("");
// Popup.smallpopup("hi", getApplicationContext());
}
});
radiorecent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
recentlist.setVisibility(View.VISIBLE);
tex1.setVisibility(View.VISIBLE);
contactlayout.setVisibility(View.GONE);
targetdevice.setText("");
}
});
radiocontact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
recentlist.setVisibility(View.GONE);
contactlayout.setVisibility(View.VISIBLE);
tex1.setVisibility(View.GONE);
targetdevice.setText("");
LoadContact loadContact = new LoadContact();
loadContact.execute();
}
});
return view;
}
public class LoadContact extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
// Get Contact list from Phone
if (phones != null) {
Log.e("count", "" + phones.getCount());
if (phones.getCount() == 0) {
// Toast.makeText(Requestor.this, "No contacts in your contact list.", Toast.LENGTH_LONG).show();
}
while (phones.moveToNext()) {
Log.d("Contact Class Called","");
Bitmap bit_thumb = null;
String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// String EmailAddr = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA2));
String image_thumb = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
try {
if (image_thumb != null) {
bit_thumb = MediaStore.Images.Media.getBitmap(resolver, Uri.parse(image_thumb));
} else {
Log.e("No Image Thumb", "--------------");
}
} catch (IOException e) {
e.printStackTrace();
}
ContactListSelectUser contactListSelectUser = new ContactListSelectUser();
contactListSelectUser.setThumb(bit_thumb);
contactListSelectUser.setName(name);
contactListSelectUser.setPhone(phoneNumber);
contactListSelectUser.setEmail(id);
// contactListSelectUser.setCheckedBox(false);
// if (!contactListSelectUsers.contains(contactListSelectUser.getPhone())) {
contactListSelectUsers.add(contactListSelectUser);
//}
}
} else {
Log.e("Cursor close 1", "----------------");
}
//phones.close();
//System.out.println(contactListSelectUsers.size());
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter = new ContactListAdapter(contactListSelectUsers, getActivity());
listView.setAdapter(adapter);
// Select item on listclick
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.e("search", "here---------------- listener");
ContactListSelectUser data = contactListSelectUsers.get(i);
targetdevice.setText(data.getPhone());
}
});
listView.setFastScrollEnabled(true);
}
}
/* #Override
protected void onStop() {
super.onStop();
phones.close();
}*/
}
Custom Adapter class code:
public class ContactListAdapter extends BaseAdapter implements Filterable {
public List<ContactListSelectUser> _data;
private ArrayList<ContactListSelectUser> arraylist;
Context _c;
ViewHolder v;
RoundImage roundedImage;
private Filter filter = new CustomFilter();
public ContactListAdapter(List<ContactListSelectUser> contactListSelectUsers, Context context) {
_data = contactListSelectUsers;
_c = context;
this.arraylist = new ArrayList<ContactListSelectUser>();
this.arraylist.addAll(_data);
}
#Override
public int getCount() {
return _data.size();
}
#Override
public Object getItem(int i) {
return _data.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View view = convertView;
if (view == null) {
LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.contact_info, null);
Log.e("Inside", "here--------------------------- In view1");
} else {
view = convertView;
Log.e("Inside", "here--------------------------- In view2");
}
v = new ViewHolder();
v.title = (TextView) view.findViewById(R.id.name);
// v.check = (CheckBox) view.findViewById(R.id.check);
v.phone = (TextView) view.findViewById(R.id.no);
v.imageView = (ImageView) view.findViewById(R.id.pic);
final ContactListSelectUser data = (ContactListSelectUser) _data.get(i);
v.title.setText(data.getName());
// v.check.setChecked(data.getCheckedBox());
v.phone.setText(data.getPhone());
// Set image if exists
try {
if (data.getThumb() != null) {
v.imageView.setImageBitmap(data.getThumb());
} else {
v.imageView.setImageResource(R.mipmap.ic_launcher);
}
// Seting round image
Bitmap bm = BitmapFactory.decodeResource(view.getResources(), R.mipmap.ic_launcher); // Load default image
roundedImage = new RoundImage(bm);
v.imageView.setImageDrawable(roundedImage);
} catch (OutOfMemoryError e) {
// Add default picture
v.imageView.setImageDrawable(this._c.getDrawable(R.mipmap.ic_launcher));
e.printStackTrace();
}
Log.e("Image Thumb", "--------------" + data.getThumb());
/*// Set check box listener android
v.check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CheckBox checkBox = (CheckBox) view;
if (checkBox.isChecked()) {
data.setCheckedBox(true);
} else {
data.setCheckedBox(false);
}
}
});*/
view.setTag(data);
return view;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
_data.clear();
if (charText.length() == 0) {
_data.addAll(arraylist);
} else {
for (ContactListSelectUser wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault())
.contains(charText)) {
_data.add(wp);
}
}
}
notifyDataSetChanged();
}
#Override
public Filter getFilter() {
return filter;
}
static class ViewHolder {
ImageView imageView;
TextView title, phone;
CheckBox check;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
_data.clear();
FilterResults filterResults = new FilterResults();
filterResults.values = _data;
filterResults.count = _data.size();
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
if (filterResults.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
below is logcat where u can see data is fetched while I choose back fragment but not set to listview.
E/Inside: here--------------------------- In view1
E/Image Thumb: --------------null
E/Inside: here--------------------------- In view1
E/Image Thumb: --------------null
I/TextInputLayout: EditText added is not a TextInputEditText. Please switch to using that class instead.
E/count: 2
E/No Image Thumb: --------------
E/No Image Thumb: --------------
E/count: 2
E/count: 2
implements Filterable in BaseAdapter
public class ContactListAdapter extends BaseAdapter implements Filterable
and add value :
private Filter filter = new CustomFilter();
and create class in your baseAdapter:
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
_data.clear();
if (arraylist != null && constraint != null) {
for (int i = 0; i < arraylist.size(); i++) {
if (arraylist.get(i).toString().toLowerCase().contains(constraint)) {
_data.add(arraylist.get(i));
}
}
}
FilterResults results = new FilterResults();
results.values = _data;
results.count = _data.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
add in your baseAdapter class:
#Override
public Filter getFilter() {
return filter;
}
my adapter for example:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CustomArrayAdapter extends BaseAdapter implements Filterable{
private LayoutInflater mInflater;
private final Context context;
private List<String> mItems;
private Filter filter = new CustomFilter();
private ArrayList<String>mItemsSuggestion = new ArrayList<String>();
public CustomArrayAdapter(Context context, String[] values) {
this.context = context;
mItems = Arrays.asList(values);
}
#Override
public int getCount() {
return mItemsSuggestion.size();
}
#Override
public Object getItem(int position) {
return mItemsSuggestion.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View oneView = mInflater.inflate(R.layout.towar_list, parent, false);
TextView text = (TextView)oneView.findViewById(R.id.towaryAllList);
text.setText(mItemsSuggestion.get(position).toString());
return oneView;
}
#Override
public Filter getFilter() {
return filter;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
mItemsSuggestion.clear();
if (mItems != null && constraint != null) {
for (int i = 0; i < mItems.size(); i++) {
if (mItems.get(i).toString().toLowerCase().contains(constraint)) {
mItemsSuggestion.add(mItems.get(i));
}
}
}
FilterResults results = new FilterResults();
results.values = mItemsSuggestion;
results.count = mItemsSuggestion.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
I solved it now. The issue was only placing search view code in radiocontact on click listeners instead of in createview method directly.
After apply filter on custom gridView productsListHolder.add_to_cart.setOnClickListener did not get the correct item position, it provides the result on the basis of previous arrangement as were before filter records.
How may I able to get the correct item of gridView after filtering?
And I wonder How Filterable does work?
public class GridAdapter extends BaseAdapter implements Filterable {
public interface BtnClickListener {
public abstract void onBtnClick(String position);
}
private BtnClickListener mClickListener = null;
Context context;
private ArrayList<Products> filteredProducts;
private ArrayList<Products> products;
private ItemFilter prodFilter = null;
private LayoutInflater inflater;
public GridAdapter(Context context, ArrayList<Products> products, BtnClickListener listener) {
this.context = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.products = products;
this.filteredProducts = products;
mClickListener = listener;
}
public class ProductsListHolder{
public ImageView prod_img;
public TextView prod_price;
public Button prod_cart;
public TextView prod_desc;
public Button add_to_cart;
}
public ArrayList<Products> getProducts() {
return products;
}
public void setProducts(ArrayList<Products> products) {
this.products = products;
}
public GridAdapter(){
}
#Override
public int getCount() {
if(products!=null)
return products.size();
return 0;
}
#Override
public Object getItem(int position) {
if(products!=null && position >=0 && position<getCount() )
return products.get(position);
return null;
}
#Override
public long getItemId(int position) {
if(products!=null && position >=0 && position<getCount() ){
Products temp = products.get(position);
return products.indexOf(temp);
}
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ProductsListHolder productsListHolder;
if(view == null){
view = inflater.inflate(R.layout.product_adapter, parent, false);
productsListHolder = new ProductsListHolder();
productsListHolder.prod_img = (ImageView) view.findViewById(R.id.prod_img);
productsListHolder.prod_price = (TextView) view.findViewById(R.id.prod_price);
productsListHolder.prod_desc = (TextView) view.findViewById(R.id.prod_desc);
productsListHolder.add_to_cart = (Button) view.findViewById(R.id.add_to_cart);
productsListHolder.add_to_cart.setTag(products.get((int) getItemId(position)).getId());
view.setTag(productsListHolder);
}
else{
productsListHolder = (ProductsListHolder) view.getTag();
}
productsListHolder.add_to_cart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mClickListener != null)
mClickListener.onBtnClick((String) v.getTag());
}
});
Products product = products.get(position);
setProduct(position,productsListHolder,product);
return view;
}
private void setProduct(int position, final ProductsListHolder productsListHolder, Products p) {
Picasso.with(context).load(p.getImageResours()).into(new Target(){
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
productsListHolder.prod_img.setBackground(new BitmapDrawable(context.getResources(), bitmap));
}
#Override
public void onBitmapFailed(final Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(final Drawable placeHolderDrawable) {
}
});
productsListHolder.prod_price.setText("Rs: ".concat(Integer.toString(p.getPrice())));
productsListHolder.prod_desc.setText(p.name);
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
#Override
public Filter getFilter() {
if(prodFilter == null)
prodFilter = new ItemFilter();
return prodFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toUpperCase();
FilterResults results = new FilterResults();
final ArrayList<Products> list = filteredProducts;
int count = list.size();
final ArrayList<Products> nlist = new ArrayList<Products>(count);
Products filtPro;
if (constraint == null || constraint.length() == 0) {
results.values = filteredProducts;
results.count = filteredProducts.size();
}
else {
for (int i = 0; i < count; i++) {
filtPro = list.get(i);
if (filtPro.getName().toUpperCase().contains(filterString)) {
nlist.add(filtPro);
}
}
results.values = nlist;
results.count = nlist.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
products = (ArrayList<Products>) results.values;
notifyDataSetChanged();
}
}
}
I created custom adapter by extending BaseAdapter and implementing Filterable interface. This adapter is used for suggest phone number to user when they type a contact number or contact person name.ArrayList<String> data contain those data with the pattern of "person name:number" which are extracted from phone.
It's working find except for one issue. If I search for contacts start with letter "A" it's show the data correctly. If I delete that and type "B" again it shows both contacts start with "A" and "B". I know that I have to clear ArrayList<String> matchedResults(Check the code) in some method before add new data but when I did that It gave me an empty ArrayList. In which method at which point I should do that or is there a different solution for this ?
here's the code
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<String> data;
private ArrayList<String> matchedResults = new ArrayList<String>();
public AutoCompleteAdapter(Context context, ArrayList<String> namesAndNumbers) {
this.context = context;
this.data = namesAndNumbers;
}
#Override
public int getCount() {
return matchedResults.size();
}
#Override
public String getItem(int position) {
return matchedResults.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, parent, false);
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView numberTextView = (TextView) view.findViewById(R.id.number);
String[] split = matchedResults.get(position).split(":");
nameTextView.setText(split[0]);
numberTextView.setText(split[1]);
return view;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null || constraint.length() != 0) {
for (String loop:data) {
int charSequenceSize = constraint.length();
if(onlyText(constraint.toString()) && !matchedResults.contains(loop)){
String[] split = loop.split(":");
String substring = split[0].substring(0, charSequenceSize);
if (substring.equalsIgnoreCase(constraint.toString())){
matchedResults.add(loop);
}
}else if(onlyNumbers(constraint.toString())){
String[] split = loop.split(":");
String substring = split[1].substring(0, charSequenceSize);
if (substring.equals(constraint.toString()) && !matchedResults.contains(loop) ){
matchedResults.add(loop);
}
}
}
}
results.values = matchedResults;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
results.values = matchedResults;
notifyDataSetChanged();
}
};
}
public boolean onlyText(String text) {
boolean result = false;
if (Pattern.matches("[a-zA-Z ]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
public boolean onlyNumbers(String text) {
boolean result = false;
if (Pattern.matches("[0-9+]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
}
update your filter to this
#Override
public Filter getFilter() {
return nameFilter;
}
Filter nameFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
matchedResults.clear();
for (String item : data) {
if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
matchedResults.add(item);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = matchedResults;
filterResults.count = matchedResults.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<String> filteredList = (ArrayList<String>) results.values;
if (results != null && results.count > 0) {
data.clear();
for (String c : filteredList) {
data.add(c);
}
notifyDataSetChanged();
}
}
};
So your entire code it be like this :
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<String> data;
private ArrayList<String> matchedResults = new ArrayList<String>();
public AutoCompleteAdapter(Context context, ArrayList<String> namesAndNumbers) {
this.context = context;
this.data = namesAndNumbers;
}
#Override
public int getCount() {
return matchedResults.size();
}
#Override
public String getItem(int position) {
return matchedResults.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, parent, false);
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView numberTextView = (TextView) view.findViewById(R.id.number);
String[] split = matchedResults.get(position).split(":");
nameTextView.setText(split[0]);
numberTextView.setText(split[1]);
return view;
}
#Override
public Filter getFilter() {
return nameFilter;
}
Filter nameFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
matchedResults.clear();
for (String item : data) {
if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
matchedResults.add(item);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = matchedResults;
filterResults.count = matchedResults.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<String> filteredList = (ArrayList<String>) results.values;
if (results != null && results.count > 0) {
data.clear();
for (String c : filteredList) {
data.add(c);
}
notifyDataSetChanged();
}
}
};
public boolean onlyText(String text) {
boolean result = false;
if (Pattern.matches("[a-zA-Z ]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
public boolean onlyNumbers(String text) {
boolean result = false;
if (Pattern.matches("[0-9+]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
}
I hope to be helpful for you .