14

I'm new to working with floating action button and trying to get a few of the basic things working today. Currently I am stuck on getting the onClick functionality to work. I pulled most of the code from googles FAB basic example, and in there it has an onChecked method which sends a string to a logger to show you have clicked it.

@Override
public void onCheckedChanged(FloatingActionButton fabView, boolean isChecked) {
    // When a FAB is toggled, log the action.

    switch (fabView.getId()){
        case R.id.fab_1:
            break;
        default:
            break;
    }
}

I was thinking I'd be able to replace the functionality in there but that had no affect. So I tried to create the onClickListener like you would with any other button but that also had no affect. I am not sure how to continue since neither option worked. my goal is just to produce a dialog when the floating action button is clicked, but for now I am just trying to use a placeholder alert dialog.

This is the FloatingActionButtonFragment class:

public class FloatingActionButtonFragment extends Fragment implements FloatingActionButton.OnCheckedChangeListener {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fab_layout, container, false);

        // Make this {@link Fragment} listen for changes in both FABs.
        FloatingActionButton fab1 = (FloatingActionButton) rootView.findViewById(R.id.fab_1);
        fab1.setOnCheckedChangeListener(this);

        fab1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setMessage("Are you sure?")
                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // User cancelled the dialog
                            }
                        });
                // Create the AlertDialog object and return it
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });
        return rootView;
    }

    @Override
    public void onCheckedChanged(FloatingActionButton fabView, boolean isChecked) {
        // When a FAB is toggled, log the action.

        switch (fabView.getId()){
            case R.id.fab_1:
                break;
            default:
                break;
        }
    }

}

And here is the FloatingActionButton class:

public class FloatingActionButton extends FrameLayout implements Checkable {

    /**
     * Interface definition for a callback to be invoked when the checked state
     * of a compound button changes.
     */
    public static interface OnCheckedChangeListener {

        /**
         * Called when the checked state of a FAB has changed.
         *
         * @param fabView   The FAB view whose state has changed.
         * @param isChecked The new checked state of buttonView.
         */
        void onCheckedChanged(FloatingActionButton fabView, boolean isChecked);
    }

    /**
     * An array of states.
     */
    private static final int[] CHECKED_STATE_SET = {
            android.R.attr.state_checked
    };

    private static final String TAG = "FloatingActionButton";

    // A boolean that tells if the FAB is checked or not.
    private boolean mChecked;

    // A listener to communicate that the FAB has changed it's state
    private OnCheckedChangeListener mOnCheckedChangeListener;

    public FloatingActionButton(Context context) {
        this(context, null, 0, 0);
    }

    public FloatingActionButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0, 0);
    }

    public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr,
                                int defStyleRes) {
        super(context, attrs, defStyleAttr);

        setClickable(true);

        // Set the outline provider for this view. The provider is given the outline which it can
        // then modify as needed. In this case we set the outline to be an oval fitting the height
        // and width.
        setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setOval(0, 0, getWidth(), getHeight());
            }
        });

        // Finally, enable clipping to the outline, using the provider we set above
        setClipToOutline(true);
    }

    /**
     * Sets the checked/unchecked state of the FAB.
     * @param checked
     */
    public void setChecked(boolean checked) {
        // If trying to set the current state, ignore.
        if (checked == mChecked) {
            return;
        }
        mChecked = checked;

        // Now refresh the drawable state (so the icon changes)
        refreshDrawableState();

        if (mOnCheckedChangeListener != null) {
            mOnCheckedChangeListener.onCheckedChanged(this, checked);
        }
    }

    /**
     * Register a callback to be invoked when the checked state of this button
     * changes.
     *
     * @param listener the callback to call on checked state change
     */
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        mOnCheckedChangeListener = listener;
    }

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

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

    /**
     * Override performClick() so that we can toggle the checked state when the view is clicked
     */
    @Override
    public boolean performClick() {
        toggle();
        return super.performClick();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // As we have changed size, we should invalidate the outline so that is the the
        // correct size
        invalidateOutline();
    }

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

There isn't much to either class at this point, they are mostly husks, but I just want to get this basic functionality down before I continue, and being the noob I am, I don't know why this wouldn't work.

erp
  • 2,950
  • 9
  • 45
  • 90
  • you should be using the FAB that is in the Support Design library – tyczj Jun 16 '15 at 19:33
  • Mind linking me to something useful? This is first time working with FAB anyways, so I just took code from one of Google's samples. That wasn't from support design library? – erp Jun 16 '15 at 19:35
  • http://developer.android.com/reference/android/support/design/widget/FloatingActionButton.html – tyczj Jun 16 '15 at 19:37
  • So what's the benefit over what I have done, not that any of this helps the original problem? – erp Jun 16 '15 at 19:44
  • The benefit is that this is the official FAB from google which is consistent with the design guidelines. I use it and onCLickListener Works fine – tyczj Jun 16 '15 at 19:47
  • Ok thanks. But would this mean I wouldn't need a lot of the other code from these 2 classes? Or would this just replace my ` – erp Jun 16 '15 at 19:49
  • right you just need to import the design library and delete the classes you made – tyczj Jun 16 '15 at 19:50
  • Ok. do you know of any examples I could view of this? The way I have it now is pretty integrated. Like the FAB is inside of a `FrameLayout` in a file `fab_layout.xml`, and then that frame layout is included in the `activity_main.xml`. I am a beginner so it's hard for me to talk _too_ intelligently about it. – erp Jun 16 '15 at 19:58
  • here is a full example that implements all the new design library stuff https://github.com/chrisbanes/cheesesquare – tyczj Jun 16 '15 at 20:00
  • dang. that's a thorough example. I'll look it over. Thanks – erp Jun 16 '15 at 20:07
  • @tycj did you have any luck witht he cheesesquare example? I'm doing exactly the same thing but my floating action button appears to be a square on lollipop..any idea? – Mr.Noob Aug 07 '15 at 08:29
  • 1
    Yeah. I actually used the cheesesquare as a baseline to move forward. It already had a few things I wanted built in, FAB and snackbar. I got rid of the Nav drawer, and some of the other stuff. One thing I noticed with the demo tho is that originally my FAB wasn't actually floating, but once I updated the dependencies, it worked fine. It's a solid example, and I do recommend checking it out. Might need to update some of the dependencies though, Like the receding action bar button placement isn't right by default, but that was an error with the library. – erp Aug 07 '15 at 14:02

3 Answers3

36

If you are not already heading for deadline, you must change the floating action button to the one provided by google in design library just follow http://android-developers.blogspot.in/2015/05/android-design-support-library.html

Add to the XML Layout:

<android.support.design.widget.FloatingActionButton
        android:id="@+id/myFAB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/your_icon"
        app:elevation="4dp"
        ... />

Add to the code behind:

FloatingActionButton myFab = (FloatingActionButton) myView.findViewById(R.id.myFAB); 
myFab.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
        doMyThing(); 
    } 
});

For more details follow : FloatingActionButton example with Support Library

Community
  • 1
  • 1
Ashish Rawat
  • 5,541
  • 1
  • 20
  • 17
9

Actually now with android support library it was very easy to add FAB and to customize it with click listeners

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // FAB Action goes here
        }
    });

Reference : http://androidgifts.com/android-material-design-floating-action-button-tutorial/

Blinxen
  • 807
  • 2
  • 13
  • 26
Fareed
  • 560
  • 2
  • 7
  • 23
3

To use dialog/Alertdialog with the floating action button you're using, try changing your onClick(View v) from this

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

to

 AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
onexf
  • 3,674
  • 3
  • 22
  • 36