Search code examples
positioncodenameonefloating-action-button

Codename One - Multiple FABs and their positioning


Following the suggestions from the material design about FABs, I do have an instance where I have need for 2 FABs in a single form. (Good article and good site in general if you are new to this: https://material.io/design/components/buttons-floating-action-button.html)

By adding a FAB to the content pane, it will be put on the layered pane, in the horizontal and vertical alignment as specified during the bind call:

fab1.bindFabToContainer(getContentPane(), Component.RIGHT, Component.BOTTOM);

Now however, when I add a second FAB to the same bottom right corner, they will appear left to right, next to each other. I would like to have the option to have them on top of each other, as in google maps or as the SUB Fab Items appear, when invoked.

Things I tried:

  1. applying individual UIIDs and themeing them with the margin constraint, deriving the rest of the UIID from FloatingActionButton. my UIID seems to be ignored completely, as the placement of the buttons is way of to what my margins determine.
  2. adding the second FAB to another position of the layered pane and work with a margin on this FAB only (a TOP margin, based of the right center location where it should be, to place it just above the first FAB)

fab2.bindFabToContainer(getContentPane(), Component.RIGHT, Component.CENTER);

However, this does not place only the second FAB in the center, but moves both FABs to this location. So I am back to the original problem of my margins not being applied properly.

Is it possible to individually position multiple FABs correctly in a single form or does CN1 enforce a strict "one-FAB-only" policy, following material design guidelines?

Thank you.

EDIT with solution:

  1. add the first FAB to your form with the normal "bindFabToContainer" call.

  2. for the second FAB, use the layered pane and manually add and layout the FAB in that layered pane. The following code adds the 2nd FAB just above the first, like a sub FAB would appear

Solution:

fab2 = FloatingActionButton.createFAB(FontImage.MATERIAL_ATTACH_MONEY);
Container layer = getLayeredPane(getClass(), true);
FlowLayout flow = new FlowLayout(RIGHT);
flow.setValign(BOTTOM);
layer.setLayout(flow);
layer.add(fab2 );
fab2.getAllStyles().setMarginUnit(Style.UNIT_TYPE_DIPS);
fab2.getAllStyles().setMarginBottom(15);

Solution

  • The material design guideline includes sub fabs not multiple fabs which are strongly discoraged. You might be thinking of speed dial. Which you can accomplish via:

    fab.createSubFab(otherFab1);
    fab.createSubFab(otherFab2);
    fab.createSubFab(otherFab3);
    

    If you still want to add another FAB you can do so by adding it manually to a different layer:

    Container layer = parentForm.getLayeredPane(getClass(), true);
    FlowLayout flow = new FlowLayout(LEFT);
    flow.setValign(BOTTOM);
    layer.setLayout(flow);
    layer.add(fab2);
    

    This will place the second fab at the bottom left. You can change the layout code to place it in a different location.