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.
Related
This is my Recycler View adapter class:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.viewHolder> implements Filterable {
Context context;
OnBoardingFirstScreen activity;
public static ArrayList<CountryCodeModel> arrayList,arrayListFiltered;
public CustomAdapter(Context context, ArrayList<CountryCodeModel> arrayList, OnBoardingFirstScreen activity) {
this.context = context;
this.arrayList = arrayList;
this.arrayListFiltered = arrayList;
this.activity = activity;
}
#Override
public viewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.country_code_item, viewGroup, false);
/*view.measure(
View.MeasureSpec.makeMeasureSpec(200, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));*/
return new viewHolder(view);
}
#Override
public void onBindViewHolder(viewHolder viewHolder, int position) {
// viewHolder.name.setText(arrayListFiltered.get(position).getCountry()+ " " +
// "(" + arrayListFiltered.get(position).getCode() + ")");
String textdotted = arrayListFiltered.get(position).getCountry();
if (textdotted.length() >= 30) {
textdotted= textdotted.substring(0, 30)+ "...";
} else {
textdotted= textdotted;
}
viewHolder.name.setText(textdotted+ " (" + arrayListFiltered.get(position).getCode() + ")");
int imagee =arrayListFiltered.get(position).getFlag();
Picasso.get().load(imagee).resize(300, 300).centerCrop().into(viewHolder.image);
Picasso.get().load(imagee).fit();
//Picasso.get().load(imagee).fit().resize(300, 300).centerCrop().into(viewHolder.image);
viewHolder.layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((OnBoardingFirstScreen)activity).onClickCountryItem(position, arrayListFiltered);
}
});
}
#Override
public int getItemCount() {
int limit = 4;
if(arrayListFiltered.size()> limit){
return limit;
}
else {
return arrayListFiltered.size();
}
}
public class viewHolder extends RecyclerView.ViewHolder {
TextView name;
ShapeableImageView image;
LinearLayout layout;
public viewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.country_name);
image = (ShapeableImageView) itemView.findViewById(R.id.flagimg);
layout = (LinearLayout) itemView.findViewById(R.id.layout);
// itemView.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v) {
//
//
// Toast.makeText(context,arrayListFiltered.get(getAdapterPosition()).getCountry(),Toast.LENGTH_LONG).show();
// }
// });
}
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<CountryCodeModel> arrayListFilter = new ArrayList<CountryCodeModel>();
if(constraint == null|| constraint.length() == 0) {
results.count = arrayList.size();
results.values = arrayList;
} else {
for (CountryCodeModel itemModel : arrayList) {
if(itemModel.getCountry().toLowerCase().contains(constraint.toString().toLowerCase())) {
arrayListFilter.add(itemModel);
}else if(itemModel.getCode().contains(constraint.toString())) {
arrayListFilter.add(itemModel);
}
}
results.count = arrayListFilter.size();
results.values = arrayListFilter;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayListFiltered = (ArrayList<CountryCodeModel>) results.values;
if (results.count == 0) {
((OnBoardingFirstScreen)activity).NoResultfound(results.count);
arrayListFiltered.clear();
notifyDataSetChanged();
}
else {
((OnBoardingFirstScreen)activity).NoResultfound(results.count);
arrayListFiltered = (ArrayList<CountryCodeModel>)results.values;
notifyDataSetChanged();
}
}
};
return filter;
}
}
This is my recyclerview XML part:
<androidx.recyclerview.widget.RecyclerView
android:layout_width="#dimen/_200sdp"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:layout_marginBottom="#dimen/_4sdp"
android:layout_marginStart="#dimen/_2sdp"
android:id="#+id/country_codes_rv"/>
in custom adapter class if i set getItemCount() to return the size instead of limit it loads all 200 items and in xml it is wrap content lists gets out of the screen.
I want to load 4 items at a time in my list and want my recyclerview list scrollable.
i dont want to give it a specific height. it will distort my view.
I made an app with listView and I want to use search in top bar but it doesn't work.
In this program, I get the data from the firebase.
These are the codes below:
This is MainActivity code:
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int List_APP_LOADER = 0;
ArrayList<Informatin> listItem;
ListView listView;
listAdapter adapter;
DatabaseReference reference;
ArrayList<Informatin> mInformation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItem = new ArrayList<>();
listView = findViewById(R.id.list);
LoaderManager.getInstance(this).initLoader(LIST_APP_LOADER, null, this);
mInformation = new ArrayList<>();
adapter = new listAdapter(this, mInformation);
listView.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main_screen, menu);
MenuItem searchItem = menu.findItem(R.id.search_item);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
listView.getFilter().filter(newText);
return true;
}
});
return true;
}
}
This is listAdapter code
public class listAdapter extends ArrayAdapter<Informatin> implements Filterable {
List<Informatin> arrayList;
Context context;
public listAdapter(Context context, ArrayList<Informatin> informatins) {
super(context, 0, informatins);
this.context=context;
arrayList = informatins;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Informatin currentList = getItem(position);
TextView nameTextView = listItemView.findViewById(R.id.name);
TextView descriptionTextView = listItemView.findViewById(R.id.description);
TextView ageTextView = listItemView.findViewById(R.id.age);
ImageView imageView = listItemView.findViewById(R.id.image);
String firstName = currentList.getFirstName();
String lastName = currentList.getLastName();
String name = firstName + " " + lastName;
nameTextView.setText(name);
descriptionTextView.setText(currentList.getDescription());
ageTextView.setText(currentList.getAge());
return listItemView;
}
List<Informatin> informatins;
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Informatin> results = new ArrayList<>();
if (informatins == null)
informatins = arrayList;
if (constraint != null) {
if (informatins != null && informatins.size() > 0) {
for (final Informatin g : informatins) {
if (g.getFirstName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
arrayList = (ArrayList<Informatin>) results.values;
notifyDataSetChanged();
}
};
}
}
this is the picture of the problem
this is a screenshot for the problem from the device
Add this to your listadapter code:
Context context;
public listAdapter(Context context, List<Informatin> informatins) {
super();
this.context=context;
arraylist=informatins;
}
ArrayList<Informatin> informatins;
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Informatin> results = new ArrayList<Informatin>();
if (informatins == null)
informatins = arraylist;
if (constraint != null) {
if (informatins != null && informatins.size() > 0) {
for (final Information g : informatins) {
if (g.getName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
arraylist = (ArrayList<Informatin>) results.values;
notifyDataSetChanged();
}
};
}
Add this in your onquerytextchaged:
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);//replace adapter with listview name which in your case is listview as informed by you in comment
return true;
}
});
return true;
Modified MainActivity onCreate() code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItem = new ArrayList<>();
listView = findViewById(R.id.list);
LoaderManager.getInstance(this).initLoader(LIST_APP_LOADER, null, this);
mInformation = new ArrayList<>();
adapter = new listAdapter(this, mInformation);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true)//add this line
}
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();
}
}
}
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
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 .