Skip to content

Instantly share code, notes, and snippets.

@DanielGrech
Created July 24, 2014 20:58
Show Gist options
  • Save DanielGrech/b33ff4586e803c46e3a6 to your computer and use it in GitHub Desktop.
Save DanielGrech/b33ff4586e803c46e3a6 to your computer and use it in GitHub Desktop.
FloatingActionButton to simulate Material design look
<dimen name="fab_size">96dp</dimen>
<dimen name="fab_icon_size">32dp</dimen>
<dimen name="fab_size">144dp</dimen>
<dimen name="fab_icon_size">48dp</dimen>
<dimen name="fab_size">72dp</dimen>
<dimen name="fab_icon_size">24dp</dimen>
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import com.dgsd.android.shiftminer.R;
import com.dgsd.android.shiftminer.util.UiUtils;
public class FloatingActionButton extends View {
private Paint mShadowPaint;
private Paint mDrawablePaint;
private Bitmap mBitmap;
public FloatingActionButton(Context context) {
super(context);
}
public FloatingActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FloatingActionButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
{
setExpandOnTouch(true);
setLayerType(LAYER_TYPE_SOFTWARE, null);
setWillNotDraw(false);
mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mShadowPaint.setStyle(Paint.Style.FILL);
mShadowPaint.setShadowLayer(10.0f, 0.0f, 3.5f, Color.argb(100, 0, 0, 0));
mDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
@Override
protected void onDraw(Canvas canvas) {
final int w = getWidth();
final int h = getHeight();
canvas.drawCircle(w / 2, h / 2, w / 2.6f, mShadowPaint);
if (mBitmap != null) {
canvas.drawBitmap(mBitmap,
(w - mBitmap.getWidth()) / 2, (h - mBitmap.getHeight()) / 2, mDrawablePaint);
}
}
public void setExpandOnTouch(boolean expand) {
setOnTouchListener(expand ? new FabTouchListener() : null);
}
public void setFloatingActionIcon(final int iconRes) {
UiUtils.onPreDraw(this, new Runnable() {
@Override
public void run() {
final Resources r = getResources();
final int viewSize = Math.min(getWidth(), getHeight());
final int idealIconSize = r.getDimensionPixelSize(R.dimen.fab_icon_size);
final int iconSize = viewSize == 0 ? idealIconSize :
Math.min(viewSize, idealIconSize);
final Bitmap bm = BitmapFactory.decodeResource(r, iconRes);
final BitmapDrawable iconDrawable = new BitmapDrawable(r, Bitmap.createScaledBitmap(
bm, iconSize, iconSize, true));
mBitmap = iconDrawable.getBitmap();
invalidate();
}
});
}
public void setFloatingActionColor(int color) {
mShadowPaint.setColor(color);
invalidate();
}
private static class FabTouchListener implements OnTouchListener {
private static final int BOUNCH_DURATION = 100;
private static final DecelerateInterpolator mDecelerateInterpolator
= new DecelerateInterpolator();
private static final OvershootInterpolator mOvershootInterpolator
= new OvershootInterpolator(10);
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
v.animate().setInterpolator(mDecelerateInterpolator)
.scaleX(1.15f).scaleY(1.15f).setDuration(BOUNCH_DURATION);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
v.animate().setInterpolator(mOvershootInterpolator)
.scaleX(1f).scaleY(1f).setDuration(BOUNCH_DURATION);
}
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment