thoughtbot / expandable-recycler-view

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

CheckableChildRecyclerViewAdapter check mark of CheckedTextView gets reset #67

Closed yavski closed 3 weeks ago

yavski commented 7 years ago
  1. Say view item at index 20 is a group that's been expanded
  2. Scroll up only as little as it's needed for the view at index 19 to go off the screen
  3. Scroll down to the expanded group view such that it's fully visible
  4. Observe the state of the check mark

Actual result: The check mark has been reset to its collapsed state Expected result: The check mark remains in expanded state

GiorgiSheklashvili commented 7 years ago

I have the same problem, my check marks are changing position, for example when I check position 19 after scroll it may be changed to 20,21,18,17 or unchecked at all. Is there any fix yet?

saurabhdhillon commented 7 years ago

@yavski @giusha @mandybess , In the parent data type maintain a boolean variable for the checkstate of that item. Everytime you scroll down or up, the view is recreated and in case you have not handled the check/uncheck depending on your selection it will revert it to default values of the view Here is the piece of code i have an arrow which changes orientation on expand and collapse, so i save the state in a boolean variable everytime i expand/collapse, and when the view is reinitialied i use the same boolean value for setting it to desired state(expand/collapse)

//class(extends ExpandableGroup) to save data for adapter 

public class StoreData extends ExpandableGroup<SearchStore> {
    public boolean expanded;

    public StoreData(String floor, List<SearchStore> items, boolean expanded) {
        super(floor, items);
        this.expanded = expanded;
    }

}

//i cast the expandable group to my class having boolean flag
 @Override
    public void onBindGroupViewHolder(FloorViewHolder holder, int flatPosition, ExpandableGroup group) {
        StoreData data = (StoreData) group;
        holder.setFloorText(data);
    }

//parent view holder

public void setFloorText(StoreData storeData) {
        this.storeData = storeData;
        tvFloor.setText(storeData.getTitle());
        if (storeData.expanded) {
            expandAnimation(storeData);
        } else {
            collapseAnimation(storeData);
        }
    }

    @Override
    public void expand() {
        super.expand();
        expandAnimation(storeData);
    }

    @Override
    public void collapse() {
        super.collapse();
        collapseAnimation(storeData);
    }

private void collapseAnimation(StoreData storeData) {
        storeData.expanded = false;
        collapseAnim = AnimationUtils.loadAnimation(context, R.anim.roatate_collapse);
        collapseAnim.setFillAfter(true);
        ivArrow.startAnimation(collapseAnim);
    }

    private void expandAnimation(StoreData storeData) {
        storeData.expanded = true;
        expandAnim = AnimationUtils.loadAnimation(context, R.anim.roatate_expand);
        expandAnim.setFillAfter(true);
        ivArrow.startAnimation(expandAnim);
    }
yavski commented 7 years ago

@saurabhdhillon yeah, I'm already doing that, the problem is that CheckableChildRecyclerViewAdapter does not invoke the callback onBindGroupViewHolder(...) for me to update the state of the view. Have a look at the attached video (pay attention to the arrow to the right of CFD Forward 53).

device-2017-08-10-114918.zip

jinujayakumar commented 6 years ago

Hi @yavski i'm facing the same issue did you find any solution?

yavski commented 6 years ago

@jinujayakumar, nope I couldn't resolve it.

mars885 commented 6 years ago

Any progress on this problem? Anyone? Same issue here. Would be interesting to find out what the cause is.

mars885 commented 6 years ago

Well, it looks like I found the problem. The thing was that the view animations were used (RotateAnimation, in my case) to rotate the icon or whatever view you are animating. This type of animation changes only where the view is drawn, but not the actual view itself. So, you first run these animations, the view is artificially animated, you scroll off and back, onDraw is called and draws the view based on its properties (which remember were not changed), and, as a result, the view appears to reset its state. So to solve it, you basically need to replace view animations with property animations.

tjwpdl commented 6 years ago

Thanks, I had to change many things but I got it working with @saurabhdhillon's post + @mars885's post, and this is how I did the property animations:

private void animateExpand2(model_category category){ // property animation
    category.expanded = true;
    ObjectAnimator animation = ObjectAnimator.ofFloat(ivCategoryArrow, "rotation", 180f);
    animation.setDuration(0);
    animation.start();
}

private void animateCollapse2(model_category category){ // property animation
    category.expanded = false;
    ObjectAnimator animation = ObjectAnimator.ofFloat(ivCategoryArrow, "rotation", 0f);
    animation.setDuration(0);
    animation.start();
}
pavelsust commented 5 years ago

@tjwpdl can you share your code i am also facing this issue.

liguopengbenli commented 2 years ago

I try all that and it still has some issues. finally I notice I it's a recycleview in scroll view. I Have to set android:nestedScrollingEnabled="false" and parent scroll view to nested scroll view, It works well. I don't use the properties animation or anthing else. The expand and collapse callback works now.

  override fun expand() {
        super.expand()
        toggleArrow(arrow, true)
    }

    override fun collapse() {
        super.collapse()
        toggleArrow(arrow, false)
    }