thoughtbot / expandable-recycler-view

Custom Android RecyclerViewAdapters that collapse and expand
https://robots.thoughtbot.com/introducing-expandablerecyclerview
MIT License
2.12k stars 403 forks source link

Collapse All parents when another one is clicked #85

Closed ziselos closed 1 month ago

ziselos commented 7 years ago

Is it possible to collapse the expanded parent when another one is clicked? So as only one parent to be expanded each time.

abdyer commented 7 years ago

@ziselos I accomplished that by overriding onGroupExpanded in my adapter:

    override fun onGroupExpanded(expandedGroup: ExpandableGroup<*>) {
        groups.filterNot { group -> group == expandedGroup }
                .filter { group -> isGroupExpanded(group) }
                .forEach { group -> toggleGroup(group) }
    }
ziselos commented 7 years ago

@abdyer Thank you for your respnose. If i got it right your code is in Kotlin, but i am not familiar with. Can you help me write it using java? I tried to collapse all parents except the one was clicked but it did not work. Thanks in advance.

ashfaq22iit commented 7 years ago

how can i get this expandedGroup?

Lihacovs commented 7 years ago

To make it on Java, bind mGroups in adapter constructor:

List<? extends ExpandableGroup> mGroups;

        CategoryAdapter(List<? extends ExpandableGroup> groups) {
            super(groups);
            mGroups = groups;
        }

Now you can try to override onGroupExpanded method in your adapter, something like this:

@Override public void onGroupExpanded(int positionStart, int itemCount) {
            if (itemCount > 0) {
                int groupIndex = expandableList.getUnflattenedPosition(positionStart).groupPos;
                notifyItemRangeInserted(positionStart, itemCount);
                for (ExpandableGroup grp : mGroups) {
                    if (grp != mGroups.get(groupIndex)) {
                        if (this.isGroupExpanded(grp)) {
                            this.toggleGroup(grp);
                            this.notifyDataSetChanged();
                        }
                    }
                }
            }
        }

code is not tested, probably it can produce errors on some cases. If you can develop working solution, please post results here

ziselos commented 7 years ago

Thanks for the response @Lihacovs ! I'll try it and if i find a working solution i will post the code.

subairariyil commented 7 years ago

Add this line if the above snippest didnt work. adapter.notifyParentItemChanged(lastExpandedPosition);

abunayem commented 7 years ago

work. but animation has gone. on collapsing group item.

iamsibasish commented 7 years ago

@Lihacovs your solution work well.Just if we have any animation on View Holder then is will not execute.So we can fix it partially by overriding the onBindViewHolder method. But the thing is that with every expand all the collapsed viewholder execute the animation.

  @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ExpandableListPosition listPos = expandableList.getUnflattenedPosition(position);
        ExpandableGroup group = expandableList.getExpandableGroup(listPos);
        switch (listPos.type) {
            case ExpandableListPosition.GROUP:
                onBindGroupViewHolder((PlaylistGroupVH) holder, position, group);

                if (isGroupExpanded(group)) {
                    ((PlaylistGroupVH) holder).expand();
                } else {
                    ((PlaylistGroupVH) holder).collapse();
                }
                break;
            case ExpandableListPosition.CHILD:
                onBindChildViewHolder((PlaylistVH) holder, position, group, listPos.childPos);
                break;
        }
    }
abbasalid commented 6 years ago

@Lihacovs Your code is working great but the animations are gone. @Sibasish1992 did you get solution for the animation?

iamsibasish commented 6 years ago

@Lihacovs i did it in the above mentioned way,but the thing is that ,With each expansion the animation on all other viewholder execute ,If you can stop the animation of other viewholders except the pressed viewholder then you can get what you want.

washul commented 6 years ago

@Lihacovs it worked, now It works fine when the previously expanded group is visible on the screen. If the group is off the screen, it will not collapse when calling toggleGroup on it. Unless I am doing something wrong?, @ziselos did you find a solution? or @Sibasish1992 can you helpme whit my problem?

truXton222 commented 6 years ago

I solved by calling this method before clicking on group.

private void collapseAll() {
    for (int i=0;i<myAdapter.getGroups().size();i++) {
        if (myAdapter.isGroupExpanded(myAdapter.getGroups().get(i))) {
            myAdapter.toggleGroup(myAdapter.getGroups().get(i));
        }
    }
}
joseluisng commented 6 years ago

@truXton222 Do you call the method before public void onGroupExpanded(int positionStart, int itemCount)?

or where is clicking on group?

RealDavid commented 4 years ago

Best solution.

` private ExpandableGroup expandedGroup;

    productAdapter.setOnGroupExpandCollapseListener(new GroupExpandCollapseListener() {
        @Override
        public void onGroupExpanded(ExpandableGroup group) {
            if (expandedGroup != null) {
                productAdapter.toggleGroup(expandedGroup);
            }
            expandedGroup = group;
        }

        @Override
        public void onGroupCollapsed(ExpandableGroup group) {
            expandedGroup=null;
        }
    });

    expandableRecyclerView.setAdapter(productAdapter);
}`