FAB.ulous is a lightweight library that help build FAB menu from a menu XML and customize the the pattern you want!
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Then add the dependency to the application module:
dependencies {
compile 'com.github.Fueled:fab.ulous:X.X.X'
}
To setup a FAB.ulous menu you need at least 3 things:
- A FloatingActionButton Widget that will be the base for the menu.
- A menu XML to build the menu from.
- A FabulousPattern that will position the menu items on the screen.
new Fabulous.Builder(this)
.setFab(binding.exampleOne)
.setFabOverlay(binding.overlay)
.setMenuId(R.menu.menu_sample)
.setMenuPattern(new LinearPattern())
.build();
Now you can capture click in onOptionsItemSelected
:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Snackbar.make(binding.getRoot(), item.getTitle(), Snackbar.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
Simply implement the FabulousPattern
:
public class LinearPattern implements FabulousPattern {
private static final int MAIN_FAB_ANIMATION_DURATION = 200;
@NotNull
@Override
public AnimatorSet getClosingAnimation(@NotNull View element, float destX, float destY) {
AnimatorSet anim = new AnimatorSet();
ObjectAnimator fabX = ObjectAnimator.ofFloat(element, View.X, destX);
fabX.setDuration(MAIN_FAB_ANIMATION_DURATION);
ObjectAnimator fabY = ObjectAnimator.ofFloat(element, View.Y, destY);
fabY.setDuration(MAIN_FAB_ANIMATION_DURATION);
anim.play(fabX).with(fabY);
return anim;
}
@NotNull
@Override
public AnimatorSet getOpeningAnimation(@NotNull View element, float destX, float destY) {
AnimatorSet anim = new AnimatorSet();
ObjectAnimator fabX = ObjectAnimator.ofFloat(element, View.X, destX);
fabX.setDuration(MAIN_FAB_ANIMATION_DURATION);
ObjectAnimator fabY = ObjectAnimator.ofFloat(element, View.Y, destY);
fabY.setDuration(MAIN_FAB_ANIMATION_DURATION);
anim.play(fabX).with(fabY);
return anim;
}
@NotNull
@Override
public FabulousPosition getFinalPosition(@NotNull View subMenu, float fabX, float fabY, int position, int menuSize) {
return new FabulousPosition(fabX, fabY - ((position + 1) * 200));
}
}
getFinalPosition
Contains the algorithm that will compute each menu item final position on the screen.getOpeningAnimation
Contains the animation to play when the menu opens.getClosingAnimation
Contains the animation to play when the menu closes.
Adding an overlay when the menu opens is very simple; add the view to your layout and let FAB.ulous know about it using setFabOverlay
.
new Fabulous.Builder(this)
.setFab(binding.exampleOne)
.setFabOverlay(binding.overlay)
.setMenuId(R.menu.menu_sample)
.setMenuPattern(new LinearPattern())
.build();
You might need to add some extra animation/transition on the main FAB when you open/close the menu.
Simple create a class that implements FabulousTransition
and then pass an instance of that class using setFabTransition
public class NinetyDegRotationTransition implements FabulousTransition {
private static final int MAIN_FAB_ANIMATION_DURATION = 200;
@NotNull
@Override
public AnimatorSet getClosingAnimation(@NotNull View element, float destX, float destY) {
AnimatorSet anim = new AnimatorSet();
ObjectAnimator fabX = ObjectAnimator.ofFloat(element, View.ROTATION, 0);
fabX.setDuration(MAIN_FAB_ANIMATION_DURATION);
anim.play(fabX);
return anim;
}
@NotNull
@Override
public AnimatorSet getOpeningAnimation(@NotNull View element, float destX, float destY) {
AnimatorSet anim = new AnimatorSet();
ObjectAnimator fabX = ObjectAnimator.ofFloat(element, View.ROTATION, 90);
fabX.setDuration(MAIN_FAB_ANIMATION_DURATION);
anim.play(fabX);
return anim;
}
}
new Fabulous.Builder(this)
.setFab(binding.exampleTwo)
.setMenuId(R.menu.menu_sample)
.setMenuPattern(new CirclePattern())
.setFabTransition(new NinetyDegRotationTransition())
.build();
If you need to an extra OnClickListener, for example, in order to track the event, simple pass a View.OnclickListener
to setFABOnClickListener
.
new Fabulous.Builder(this)
.setFab(binding.exampleTwo)
.setMenuId(R.menu.menu_sample)
.setMenuPattern(new CirclePattern())
.setFabTransition(new NinetyDegRotationTransition())
.setFABOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Analytics.trackEvent("menu_clicked");
}
})
.build();
Copyright 2016 Fueled
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.