Problem: Adding a list item prevents filter method from working. Otherwise the filter works correctly.
Expected: That the items and database are correctly updated from the both add item and filter methods.
Tested:
Probable Solution: I thought I was missing an assignment to the items list to grab the updated version of the list. After checking it seems that both add item and filter methods are grabbing the updated list. I am starting to think I don't understand how the filter method works and that I am missing a method or line that the filter needs to refresh. Would appreciate suggestions on how to find what I am missing.
private void addProjectItem() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
View view = getLayoutInflater().inflate(R.layout.project_add_layout, null);
final EditText title = view.findViewById(R.id.addProjectTitle);
final EditText description = view.findViewById(R.id.addProjectDescription);
builder.setNegativeButton(
android.R.string.cancel,
(dialog, which) -> dialog.cancel()
);
builder.setPositiveButton(
android.R.string.ok,
(dialog, which) -> {
if (!title.getText().toString().isEmpty() && !description.getText().toString().isEmpty()) {
ProjectItem item = new ProjectItem(
title.getText().toString(),
description.getText().toString(),
appDataManager.getUid(),
false
);
projectListManager.addItem(item);
adapter.updateItems(projectListManager.getList());
} else {
Toast.makeText(SecondActivity.this, projectAddError, Toast.LENGTH_SHORT).show();
}
}
);
builder.setView(view);
builder.show();
}
private class ProjectItemAdapter extends ArrayAdapter<ProjectItem> implements Filterable {
private Context context;
private List<ProjectItem> items;
private ImageButton projectCompleteButton;
private ImageButton projectDescriptionButton;
private TextView itemTitle;
private ImageButton projectJoinButton;
private ProjectItemAdapter( Context context, List<ProjectItem> items) {
super(context, -1, items);
this.context = context;
this.items = items;
}
@NonNull
@Override
public Filter getFilter() {
return projectFilter;
}
private final Filter projectFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<ProjectItem> found = new ArrayList<>();
if(constraint == null || constraint.length() == 0) {
found.addAll(projectListManager.getList());
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for(ProjectItem item : items){
if(item.getTitle().toLowerCase().contains(filterPattern)) {
found.add(item);
}
}
}
results.values = found;
results.count = found.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
addAll((List)results.values);
notifyDataSetChanged();
}
};
public void updateItems(List<ProjectItem> items) {
this.items = items;
notifyDataSetChanged();
}
@Override
public int getCount() {
return items.size();
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
// Removed as there is nothing that manipulates the list item.
return convertView;
}
}
}
Problem was with the publish results not referencing the items list and properly casting results as a collections.
Solution:
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
items.clear();
items.addAll((Collection<? extends ProjectItem>) results.values);
notifyDataSetChanged();
}