FloatingActionButton with checkable implementation

Viewed 1125

I created an Activity with an AppBar, FloatingActionButton and a RecyclerView. I implement my own FAB, because I want it to be checkable. Here is my code:

public class CheckableFloatingActionButton extends FloatingActionButton implements Checkable {

    private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};

    private boolean checked = false;
    private boolean broadcasting;

    private OnCheckedChangeListener onCheckedChangeListener;

    public interface OnCheckedChangeListener {

        void onCheckedChanged(CheckableFloatingActionButton fab, boolean isChecked);
    }

    public CheckableFloatingActionButton(Context context) {
        this(context, null);
    }

    public CheckableFloatingActionButton(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckableFloatingActionButton);
        setChecked(a.getBoolean(R.styleable.CheckableFloatingActionButton_checked, false));
        a.recycle();

    }

    @Override
    public void setChecked(boolean checked) {
        if (this.checked != checked) {
            this.checked = checked;
            refreshDrawableState();
            if (broadcasting) {
                return;
            }

            broadcasting = true;
            if (onCheckedChangeListener != null) {
                onCheckedChangeListener.onCheckedChanged(this, this.checked);
            }

            broadcasting = false;
        }
    }

    public void toggle(boolean animate) {
        if (animate) {
            setChecked(checked);
            return;
        }
        checked = !checked;
        jumpDrawablesToCurrentState();

    }

    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        onCheckedChangeListener = listener;
    }

    @Override
    public boolean performClick() {
        toggle();
        return super.performClick();
    }

    @Override
    public boolean isChecked() {
        return checked;
    }

    @Override
    public void toggle() {
        setChecked(!checked);
    }

    @Override
    public int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        }
        return drawableState;
    }

}

It's working until I scroll up/down and hide/show the FAB. As you can see, the FAB animating the drawable instead of setting immmediately. That's why (I think) the bug occurs. Is there any way to solve it?

link

2 Answers
Related