Skip to content

Instantly share code, notes, and snippets.

@cesco89
Last active August 29, 2015 14:04
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cesco89/50ddae7d38d1bcb69ff6 to your computer and use it in GitHub Desktop.
Save cesco89/50ddae7d38d1bcb69ff6 to your computer and use it in GitHub Desktop.
Android Floating Action Button (FAB). Based on this: https://github.com/FaizMalkani/FloatingActionButton with a couple of additions
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Fab">
<attr name="fabDrawable" format="reference"/>
<attr name="fabColor" format="color"/>
<attr name="fabDepth" format="integer"/>
<attr name="fabShadowRadius" format="float"/>
</declare-styleable>
</resources>
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
public class Fab extends View {
Context _context;
Paint mButtonPaint, mDrawablePaint;
Bitmap mBitmap;
int mScreenHeight;
int mScreenWidth;
float currentY;
float currentX;
float shadowRadius = 10.0f;
int distance = 2;
float pressedAlpha = 0.6f;
boolean mHidden = false;
int fabColor = Color.WHITE;
float DEPTH_1 = 1.0f;
float DEPTH_2 = 3.0f;
float DEPTH_3 = 10.0f;
float DEPTH_4 = 14.0f;
float DEPTH_5 = 19.0f;
private float mDepth = 3.0f;
Drawable myDrawable;
public static final int MODE_FROM_BOTTOM = 0;
public static final int MODE_FROM_TOP = 1;
public static final int MODE_FROM_LEFT = 2;
public static final int MODE_FROM_RIGHT = 3;
private int mMode = 0;
public Fab(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
_context = context;
parseAttrs(attributeSet,0);
init(fabColor);
}
public Fab(Context context, AttributeSet attributeSet, int defStyle)
{
super(context, attributeSet, defStyle);
_context = context;
parseAttrs(attributeSet, defStyle);
init(fabColor);
}
public Fab(Context context)
{
super(context);
_context = context;
init(fabColor);
}
private void parseAttrs(AttributeSet attrs, int defStyle) {
TypedArray a = _context.obtainStyledAttributes(attrs, R.styleable.Fab, defStyle, 0);
myDrawable = a.getDrawable(R.styleable.Fab_fabDrawable);
mBitmap = ((BitmapDrawable) myDrawable).getBitmap();
fabColor = a.getColor(R.styleable.Fab_fabColor, Color.WHITE);
distance = a.getInt(R.styleable.Fab_fabDepth, distance);
shadowRadius = a.getFloat(R.styleable.Fab_fabShadowRadius, 10.0f);
switch(distance) {
case 0:
mDepth = DEPTH_1;
break;
case 1:
mDepth = DEPTH_2;
break;
case 2:
mDepth = DEPTH_3;
break;
case 3:
mDepth = DEPTH_4;
break;
case 4:
mDepth = DEPTH_5;
break;
default:
mDepth = DEPTH_2;
}
a.recycle();
}
public void setFabColor(int color)
{
this.fabColor = color;
invalidate();
}
public void setFabDrawable(Drawable fabDrawable)
{
myDrawable = fabDrawable;
mBitmap = ((BitmapDrawable) myDrawable).getBitmap();
invalidate();
}
public void setFabShadowRadius(float radius) {
this.shadowRadius = radius;
invalidate();
}
public void setFabDepth(int depth) {
this.distance = depth;
invalidate();
}
public void setPressedAlpha(float alpha) {
this.pressedAlpha = alpha;
invalidate();
}
public void setAnimationMode(int mode) {
this.mMode = mode;
}
public void init(int fabColor)
{
setWillNotDraw(false);
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mButtonPaint.setColor(fabColor);
mButtonPaint.setStyle(Paint.Style.FILL);
mButtonPaint.setShadowLayer(shadowRadius, 0.0f, mDepth, Color.argb(100, 0, 0, 0));
mDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
invalidate();
WindowManager mWindowManager = (WindowManager) _context.getSystemService(Context.WINDOW_SERVICE);
Display display = mWindowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
mScreenHeight = size.y;
mScreenWidth = size.x;
}
@Override
protected void onDraw(Canvas canvas)
{
setClickable(true);
canvas.drawCircle(getWidth()/2, getHeight()/2,(float) (getWidth()/2.6), mButtonPaint);
canvas.drawBitmap(mBitmap, (getWidth() - mBitmap.getWidth()) / 2, (getHeight() - mBitmap.getHeight()) / 2, mDrawablePaint);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_UP)
{
setAlpha(1.0f);
}
else if(event.getAction() == MotionEvent.ACTION_DOWN)
{
setAlpha(pressedAlpha);
}
return super.onTouchEvent(event);
}
public int dpToPx(int dp)
{
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
public boolean isHidden() {
return this.mHidden;
}
public void hideFab() {
if(mHidden == false) {
currentY = getY();
currentX = getX();
ObjectAnimator mHideAnimation = null;
switch(mMode) {
case MODE_FROM_BOTTOM:
mHideAnimation = ObjectAnimator.ofFloat(this, "Y", mScreenHeight);
break;
case MODE_FROM_TOP:
mHideAnimation = ObjectAnimator.ofFloat(this, "Y", -mScreenHeight);
break;
case MODE_FROM_LEFT:
mHideAnimation = ObjectAnimator.ofFloat(this, "X", -mScreenWidth);
break;
case MODE_FROM_RIGHT:
mHideAnimation = ObjectAnimator.ofFloat(this, "X", mScreenWidth);
break;
default:
mHideAnimation = ObjectAnimator.ofFloat(this, "Y", mScreenHeight);
break;
}
mHideAnimation.setInterpolator(new AccelerateInterpolator());
mHideAnimation.start();
mHidden = true;
}
}
public void showFab()
{
if(mHidden == true)
{
ObjectAnimator mShowAnimation = null;
switch(mMode) {
case MODE_FROM_BOTTOM:
mShowAnimation = ObjectAnimator.ofFloat(this, "Y", currentY);
break;
case MODE_FROM_TOP:
mShowAnimation = ObjectAnimator.ofFloat(this, "Y", -currentY);
break;
case MODE_FROM_LEFT:
mShowAnimation = ObjectAnimator.ofFloat(this, "X", currentX);
break;
case MODE_FROM_RIGHT:
mShowAnimation = ObjectAnimator.ofFloat(this, "X", currentX);
break;
default:
mShowAnimation = ObjectAnimator.ofFloat(this, "Y", currentY);
break;
}
mShowAnimation.setInterpolator(new DecelerateInterpolator());
mShowAnimation.start();
mHidden = false;
}
}
}
<com.your.package.Fab
android:id="@+id/fabbutton"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_margin="16dp"
app:fabColor="@android:color/white"
app:fabDepth="1"
app:fabDrawable="@drawable/ic_content_new"
app:fabShadowRadius="12" />
//***Your code***
mFab = (Fab) rootView.findViewById(R.id.fabbutton);
mFab.setAnimationMode(Fab.MODE_FROM_RIGHT);
//***Your code***
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment