Zoltan Szilagyi
Zoltan Szilagyi

Reputation: 292

FloatingActionButton with checkable implementation

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

Upvotes: 3

Views: 1307

Answers (2)

Gabor
Gabor

Reputation: 7572

The FloatingActionButtonBasic sample in Android Studio includes a Checkable implementation of FloatingActionButton. It works well when you scroll up/down with the CollapsingToolbarLayout. But I think using https://developer.android.com/reference/android/widget/CompoundButton.html would be an even more elegant solution.

Upvotes: 1

Diogo Rosa
Diogo Rosa

Reputation: 756

If thats a FloatingAcionsMenu you can use a listener for when it's expanded or no, why don't you use the listener for when it's expands check if the "checked" parameter is true, and if it is fill the drawable.

 fam.setOnFloatingActionsMenuUpdateListener(new FloatingActionsMenu.OnFloatingActionsMenuUpdateListener() {
        @Override
        public void onMenuExpanded() {
          if(checked){
             //do something
          }
        }

        @Override
        public void onMenuCollapsed() {
        }
    });

Upvotes: 0

Related Questions