|
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; |
|
} |
|
} |
|
|
|
} |