Update all checkbox in nested recycler View when button in Fragment is clicked

Viewed 226

Hello I am struggling with this problem. I have a RecyclerView with checkboxes items which is nested in another RecyclerView. My problem is that I want all the checkbox to be unchecked when the user click in a button in the fragment. So how could I access the checkbox view holder from my fragment button? Thank you. Please be comprehensive with the mistakes in my code I am beginner, self-taught and it is my first app. Any help would be really appreciated.

fragment_index_category_filter.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="4dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Fragments.IndexCategoryFilterFragment">

    <!-- TODO: Update blank fragment layout -->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:gravity="center"
        app:layout_constraintTop_toTopOf="parent"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/home_activity_tb"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentInsetLeft="0dp"
            app:contentInsetRight="0dp"
            app:contentInsetEnd="0dp"
            app:contentInsetStart="0dp"
            android:gravity="center"
            android:layout_gravity="center"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <RelativeLayout
                android:id="@+id/toolbar"
                android:padding="8dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <com.google.android.material.button.MaterialButton
                    android:id="@+id/close_filters"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:layout_alignParentStart="true"
                    android:layout_centerVertical="true"
                    android:insetLeft="0dp"
                    android:insetTop="0dp"
                    android:insetRight="0dp"
                    android:insetBottom="0dp"
                    android:padding="0dp"
                    app:fabCustomSize="50dp"
                    app:icon="@drawable/cancel"
                    app:iconGravity="textStart"
                    app:iconPadding="0dp"
                    app:iconSize="32dp"
                    app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MyApp.Button.Circle" />

                <com.google.android.material.textview.MaterialTextView
                    android:id="@+id/appBarTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="Category list"
                    android:textAllCaps="false"
                    android:textColor="@color/black"
                    android:textSize="24sp" />

                <com.google.android.material.button.MaterialButton
                    android:id="@+id/save_filters"
                    app:icon="@drawable/ic_check_ok"
                    app:iconSize="32dp"
                    app:iconGravity="textStart"
                    android:layout_width="32dp"
                    android:layout_height="32dp"
                    android:padding="0dp"
                    app:iconPadding="0dp"
                    android:insetLeft="0dp"
                    android:insetTop="0dp"
                    android:insetRight="0dp"
                    android:layout_alignParentEnd="true"
                    android:layout_centerVertical="true"
                    android:insetBottom="0dp"
                    app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MyApp.Button.Circle"
                    app:fabCustomSize="50dp"
                   />

            </RelativeLayout>
        </androidx.appcompat.widget.Toolbar>
    </com.google.android.material.appbar.AppBarLayout>

    <RelativeLayout

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/appBarLayout"
        android:id="@+id/shortcuts_filter">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/clear_filters"
            style="@style/Widget.MaterialComponents.Button.OutlinedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:padding="0dp"
            android:text="Clear all"
            android:textAllCaps="false"
            android:textSize="12sp" />
        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="0dp"
            android:id="@+id/select_all_filters"
            android:textSize="12sp"
            android:text="Select all"
            android:layout_alignParentEnd="true"
            android:textAllCaps="false"
            style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>


    </RelativeLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:layout_margin="8dp"
        app:layout_constraintTop_toBottomOf="@+id/shortcuts_filter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/categorySection_rv"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:orientation="vertical"/>

</androidx.constraintlayout.widget.ConstraintLayout>

IndexCategoryFilterFragment.java

 public class IndexCategoryFilterFragment extends Fragment {
        //Initialize variable
        List<String> streamFiltersList;
        RecyclerView categorySection_rv;
        FirebaseDatabase firebaseDatabase;
        DatabaseReference dbCategoryReference;
        StreamFilterManager streamFilterManager;
        MaterialButton save_filters, clear_filters, close_fragment;
        FiltersViewModel filtersListObserver;
        private FirebaseAuth mAuth;
        FirebaseUser firebaseUser;
        String userId;
        SectionAdapter sectionAdapter;
        List<Letter> letterList;
        List<Category> categoryInLetter = new ArrayList<>();
        public FilterInterface interfaceListener;
    
    
        public IndexCategoryFilterFragment() {
            // Required empty public constructor
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            if (container != null) {
                container.removeAllViews();
            }
            // Inflate the layout for this fragment
            mAuth = FirebaseAuth.getInstance();
            firebaseUser = mAuth.getCurrentUser();
            userId = firebaseUser.getUid();
    
            View view = inflater.inflate(R.layout.fragment_index_category_filter, container, false);
            save_filters = view.findViewById(R.id.save_filters);
            categorySection_rv = view.findViewById(R.id.categorySection_rv);
            clear_filters = view.findViewById(R.id.clear_filters);
            close_fragment = view.findViewById(R.id.close_filters);
            firebaseDatabase = FirebaseDatabase.getInstance();
            dbCategoryReference = firebaseDatabase.getReference("CategoryIndexed");
    
            save_filters.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    streamFilterManager.logOutFromUserSession();
                    streamFilterManager.writeListInPref(getContext(), streamFiltersList, userId);
                    Log.d("streamFilter", "onClick: " + streamFiltersList);
                    filtersListObserver = new ViewModelProvider(requireActivity()).get(FiltersViewModel.class);
                    filtersListObserver.setFiltersList(streamFiltersList);
                    getParentFragmentManager().beginTransaction().replace(R.id.fragment_container, new Home(), "home").commit();
                }
            });
            close_fragment.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    getParentFragmentManager().popBackStack();
                }
            });
            letterList = new ArrayList<>();
            categoryInLetter = new ArrayList<>();
            sectionAdapter = new SectionAdapter(getContext(), letterList);
            categorySection_rv.setAdapter(sectionAdapter);
            firebaseCategoryIndex();
    
            return view;
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
        }
    
        @Override
        public void onResume() {
            super.onResume();
            streamFilterManager = new StreamFilterManager(getContext(), userId);
            streamFiltersList = streamFilterManager.readFilterList(getContext(), userId);
            if (streamFiltersList == null) {
                streamFiltersList = new ArrayList<>();
            }
            clear_filters.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    checkboxUpdate();
                }
            });
    
        }
    
        private void firebaseCategoryIndex() {
            // First recycler
            Query queryLetter = dbCategoryReference.orderByChild("index");
            queryLetter.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    letterList.clear();
                    for (DataSnapshot dsLetter : snapshot.getChildren()) {
                        Letter letter = dsLetter.getValue(Letter.class);
                        letterList.add(letter);
    
                    }
                    sectionAdapter.notifyDataSetChanged();
                    Log.d("letterList", "letterList: " + letterList.size());
                }
    
                @Override
                public void onCancelled(@NonNull DatabaseError error) {
    
                }
            });
    
        }
    
        // solutions testing
        public interface FilterInterface {
            void clearSelectAllFilters(Button allFilters);
        }
    
        private void checkboxUpdate() {
            // 1. get ith item of the parent recyclerView
            for(int i = 0 ; i< sectionAdapter.getItemCount();i++){
                SectionAdapter.ViewHolder viewHolder = (SectionAdapter.ViewHolder) categorySection_rv.findViewHolderForAdapterPosition(i);
                RecyclerView recyclerView = viewHolder.section_item_rv;
                ItemSectionAdapter itemSectionAdapter = (ItemSectionAdapter) recyclerView.getAdapter();
                itemSectionAdapter.update();
            }
    
        }
    }

SectionAdapter.java

public class SectionAdapter extends RecyclerView.Adapter<SectionAdapter.ViewHolder> implements IndexCategoryFilterFragment.FilterInterface {
    Context context ;
    List<Letter> letterList;

    DatabaseReference categoryListRef;

    public SectionAdapter(Context context, List<Letter> letterList) {
        this.context = context;
        this.letterList = letterList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.section_category,parent,false);
        return new SectionAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        List<Category> letterCategoryList = new ArrayList<>();
        Letter letter = letterList.get(position);
        holder.section_letter.setText(letter.getIndex());
        holder.section_title_ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int visible = holder.section_item_rv.getVisibility();
                if (visible == View.VISIBLE){
                    holder.section_item_rv.setVisibility(View.GONE);
                } else {
                    holder.section_item_rv.setVisibility(View.VISIBLE);
                }
            }
        });
        categoryListRef = FirebaseDatabase.getInstance().getReference("CategoryIndexed").child(letter.getIndex()).child("content");
        ItemSectionAdapter itemSectionAdapter = new ItemSectionAdapter(letterCategoryList);
        categoryListRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for (DataSnapshot dsLetterContent : snapshot.getChildren()){
                    Category category = dsLetterContent.getValue(Category.class);
                    category.setCheckState(true);
                    Log.d("letterList", "letterList: "+ category.getCategoryName() + " "+ category.isCheckState());
                    letterCategoryList.add(category);
                }
                itemSectionAdapter.notifyDataSetChanged();
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });
        holder.section_item_rv.setAdapter(itemSectionAdapter);


    }

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

    @Override
    public void clearSelectAllFilters(Button allFilters) {

    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public MaterialTextView section_letter;
        public RecyclerView section_item_rv;
        public LinearLayout section_title_ll;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            section_letter = itemView.findViewById(R.id.section_letter);
            section_item_rv = itemView.findViewById(R.id.section_item_rv);
            section_title_ll = itemView.findViewById(R.id.section_title_ll);

        }
    }


}

ItemSectionAdpater.java

public class ItemSectionAdapter extends RecyclerView.Adapter<ItemSectionAdapter.ViewHolder> implements IndexCategoryFilterFragment.FilterInterface {
    List<Category> categoryList;

    public ItemSectionAdapter(List<Category> categoryList) {
        this.categoryList = categoryList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.index_category_name_item,parent,false);

        return new ItemSectionAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Category category = categoryList.get(position);
        holder.indexItemCategory.setText(category.getCategoryName());
        holder.cb_categoryItem.setChecked(category.isCheckState());
    }

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

    @Override
    public void clearSelectAllFilters(Button allFilters) {

    }

    public class ViewHolder extends RecyclerView.ViewHolder {
            public TextView indexItemCategory;
            public CheckBox cb_categoryItem;
            public RelativeLayout category_item_rl;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            indexItemCategory = itemView.findViewById(R.id.indexItemCategory);
            cb_categoryItem = itemView.findViewById(R.id.cb_categoryItem);
            category_item_rl = itemView.findViewById(R.id.category_item_rl);
        }
    }

    public void update() {
        categoryList.forEach(category -> category.setCheckState(false));
        notifyDataSetChanged();
    }

}
1 Answers

Make a public method in adapter and then pass your new data with changed checked values to true, and then notify the adapter like shown below (or update the existing method with the code given below).

public void updateList(ArrayList<Category> categoryList) {
        this.categoryList = categoryList;
        notifyDataSetChanged();
}

then simply call this method wherever you need with the adapter object in your fragment.

Related