Last active
August 29, 2015 14:04
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//***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