lundi 2 août 2021

Filter a nested recyclerview, including checkboxes with a spinner

I created a nested recyclerView and created 2 Adapters, "SchrankAdapter" and "SchrankChildAdapter". The "SchrankChildAdapter" is responsible for the checkboxes and the "Schrankadapter" is responsible for the main categories.

Let me show you some screenshots for a better understanding.

Topics and SubItems with Checkboxes

SchrankAdapter:

private Context context;
private ArrayList<CategoryName> categoryTopic = new ArrayList<>();
private Map<String, String> dropDownValues = new HashMap<>();
private ArrayList<CategoryName> allValues = new ArrayList<>();
private ArrayList<CategoryName> checkedValues = new ArrayList<>();
private ArrayList<CategoryName> uncheckedValues = new ArrayList<>();
private Boolean isSearching = false;

SchrankChildAdapter childAdapter;

public SchrankAdapter(Context context, ArrayList<CategoryName> categoryTopic, Map<String, String> dropDownValues){

    this.context = context;
    this.categoryTopic = categoryTopic;
    this.dropDownValues = dropDownValues;
    allValues = new ArrayList<>(categoryTopic);
    uncheckedValues = 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(), parentItem.getCategoryName());

    if(!childAdapter.getCheckedSubList().isEmpty()) {
        uncheckedValues.add(new CategoryName(parentItem.getCategoryName(), childAdapter.getCheckedSubList()));
        System.out.println("Werte müssten enthalten sein!");
    }


    if(isSearching) {

        holder.btFolderMinus.setVisibility(View.VISIBLE);
        holder.childView.setVisibility(View.VISIBLE);
        holder.btFolderPlus.setVisibility(View.GONE);
    }
    else {

        holder.btFolderPlus.setVisibility(View.VISIBLE);
        holder.btFolderMinus.setVisibility(View.GONE);
        holder.childView.setVisibility(View.GONE);
    }

    holder.btFolderPlus.setOnClickListener(v -> {

        holder.btFolderMinus.setVisibility(View.VISIBLE);
        holder.childView.setVisibility(View.VISIBLE);
        holder.btFolderPlus.setVisibility(View.GONE);
    });

    holder.btFolderMinus.setOnClickListener(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, String categoryName) {

    childAdapter = new SchrankChildAdapter(context, categoryChildrenList, categoryName);
    recyclerView.setLayoutManager(new LinearLayoutManager(context));
    recyclerView.setAdapter(childAdapter);
}

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

private Filter searchViewFilter = 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(allValues);
            isSearching = false;

        } else {
            String filterPattern = constraint.toString().toLowerCase().trim();

            for (CategoryName item: categoryTopic) {

                for(CategoryChild subItem: item.getChildViewList()) {

                    if(subItem.getCategoryAttribute().toLowerCase().contains(filterPattern)) {
                        //subItem.setCheckBoxState(subItem.getCheckBoxState());
                        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;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        categoryTopic.clear();
        categoryTopic.addAll((ArrayList) results.values);
        notifyDataSetChanged();
    }
};

public Filter getSpinnerFilter() {
    return spinnerFilter;
}

private Filter spinnerFilter = 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 || constraint.equals("all")) {

            filteredList.addAll(allValues);

        }  else if(constraint.equals("checked")) {

                filteredList.addAll(checkedValues);

        } else if(constraint.equals("unchecked")) {

            filteredList.addAll(uncheckedValues);

        }

        FilterResults results = new FilterResults();

        if(filteredList != null) {
            results.values = filteredList;
        }
        else {
            results.values = allValues;
        }
        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;
    Spinner dropDownMenu;

    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);
        dropDownMenu = itemView.findViewById(R.id.dropDown);
    }
}

}

SchrankChildAdapter:

public class SchrankChildAdapter extends RecyclerView.Adapter<SchrankChildAdapter.ViewHolder> {

private Context context;
ArrayList<CategoryChild> childItemArrayList = new ArrayList<>();
ArrayList<CategoryName> checkedList = new ArrayList<>();
ArrayList<CategoryChild> checkedSubList = new ArrayList<>();
ArrayList<CategoryChild> uncheckedSubList = new ArrayList<>();
String categoryName;

public SchrankChildAdapter(Context context, ArrayList<CategoryChild> childItemArrayList, String categoryName) {
    this.context = context;
    this.childItemArrayList = childItemArrayList;
    this.categoryName = categoryName;
    uncheckedSubList.addAll(childItemArrayList);
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_category_item, parent, false);

    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    CategoryChild childItem = childItemArrayList.get(position);

    holder.checkBox.setText(childItem.checkBoxText);

    holder.checkBox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final boolean isChecked = holder.checkBox.isChecked();

            if(holder.checkBox.isChecked()) {
                System.out.println("Checkbox: " + childItem.getCategoryAttribute() + " is checked");
                checkedSubList.add(new CategoryChild(childItem.getCategoryAttribute()));
                deleteChidList(uncheckedSubList, childItem.getCategoryAttribute());
                notifyDataSetChanged();
            }
            else if(!holder.checkBox.isChecked()) {
                System.out.println("Checkbox: " + childItem.checkBoxText + " is unchecked");
                uncheckedSubList.add(new CategoryChild(childItem.getCategoryAttribute()));
                deleteChidList(checkedSubList, childItem.getCategoryAttribute());
                notifyDataSetChanged();
            }
        }
    });

    /*holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(holder.checkBox.isChecked()) {
                System.out.println("Checkbox: " + childItem.getCategoryAttribute() + " is checked");
                checkedSubList.add(new CategoryChild(childItem.getCategoryAttribute()));
                deleteChidList(uncheckedSubList, childItem.getCategoryAttribute());
                notifyDataSetChanged();
            }
            else if(!holder.checkBox.isChecked()) {
                System.out.println("Checkbox: " + childItem.checkBoxText + " is unchecked");
                uncheckedSubList.add(new CategoryChild(childItem.getCategoryAttribute()));
                deleteChidList(checkedSubList, childItem.getCategoryAttribute());
                notifyDataSetChanged();
            }
        }
    });

     */
}

@Override
public int getItemCount() {
    return childItemArrayList.size();
}

public ArrayList<CategoryChild> getCheckedSubList() {
    return checkedSubList;
}

public ArrayList<CategoryChild> getUncheckedSubList() {
    return uncheckedSubList;
}

private void deleteChidList(ArrayList<CategoryChild> list, String childName){

    if(list.size() > 0) {
        for(int i = 0; i < list.size(); i++) {

            if(childName.equals(list.get(i).getCategoryAttribute()))
                list.remove(i);

        }
    }
}

public class ViewHolder extends RecyclerView.ViewHolder {

    CheckBox checkBox;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        checkBox = itemView.findViewById(R.id.checkbox);
    }
}

}

So my SchrankChildAdapter is handling the onClickListener of the Checkboxes and adds the checked ones to the "checkedValues" ArrayList and the unchecked ones to "uncheckedValues" Arraylist.

Here comes the problem when I want to use those Arraylists in the "SchrankAdapater" to filter it with the spinner.

@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(), parentItem.getCategoryName());

    if(!childAdapter.getCheckedSubList().isEmpty()) {
        uncheckedValues.add(new CategoryName(parentItem.getCategoryName(), childAdapter.getCheckedSubList()));
        System.out.println("Werte müssten enthalten sein!");
    }

I expect my if-clause to respond false, whenever one or more checkboxes are clicked, but this won't happen. The problem I have is that the onBindViewHolder isn't repeating/checking it's program the whole time, only once you create it. So obviously my if-clause won't be "activated" because in the beginning no checkbox is checked.

How can I fix that and is there any other easy way to achieve this goal?




Aucun commentaire:

Enregistrer un commentaire