Back to project page FloatingActionButton.
The source code is released under:
MIT License
If you think the Android project FloatingActionButton listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.faizmalkani.floatingactionbutton; //from w w w . j a va 2s .co m import android.annotation.TargetApi; 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.os.Build; import android.util.AttributeSet; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; import android.widget.AbsListView; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class FloatingActionButton extends View { private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator(); private final Paint mButtonPaint; private final Paint mDrawablePaint; private Bitmap mBitmap; private int mColor; private boolean mHidden = false; private float mCurrentY; private Display display; protected AbsListView mListView; private static final int TRANSLATE_DURATION_MILLIS = 200; public FloatingActionButton(Context context) { this(context, null); } public FloatingActionButton(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG); TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FloatingActionButton); mColor = a.getColor(R.styleable.FloatingActionButton_color, Color.WHITE); mButtonPaint.setStyle(Paint.Style.FILL); mButtonPaint.setColor(mColor); float radius, dx, dy; radius = a.getFloat(R.styleable.FloatingActionButton_shadowRadius, 10.0f); dx = a.getFloat(R.styleable.FloatingActionButton_shadowDx, 0.0f); dy = a.getFloat(R.styleable.FloatingActionButton_shadowDy, 3.5f); int color = a.getInteger(R.styleable.FloatingActionButton_shadowColor, Color.argb(100, 0, 0, 0)); mButtonPaint.setShadowLayer(radius, dx, dy, color); Drawable drawable = a.getDrawable(R.styleable.FloatingActionButton_drawable); if (null != drawable) { mBitmap = ((BitmapDrawable) drawable).getBitmap(); } setWillNotDraw(false); try { this.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } catch (NoSuchMethodError e2) { // http://stackoverflow.com/questions/16990588/setlayertype-substitute-for-android-2-3-3 try { Method setLayerTypeMethod = this.getClass().getMethod( "setLayerType", new Class[] { int.class, Paint.class }); if (setLayerTypeMethod != null) setLayerTypeMethod.invoke(this, new Object[] { LAYER_TYPE_SOFTWARE, null }); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } WindowManager mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); display = mWindowManager.getDefaultDisplay(); Point size = getSize(); } @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) @SuppressWarnings("deprecation") protected Point getSize() { final Point point = new Point(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(point); } else { point.x = display.getWidth(); point.y = display.getHeight(); } return point; } public void setColor(int color) { mColor = color; mButtonPaint.setColor(mColor); invalidate(); } public void setDrawable(Drawable drawable) { mBitmap = ((BitmapDrawable) drawable).getBitmap(); invalidate(); } @Override protected void onDraw(Canvas canvas) { canvas.drawCircle(getWidth() / 2, getHeight() / 2, (float) (getWidth() / 2.6), mButtonPaint); if (null != mBitmap) { canvas.drawBitmap(mBitmap, (getWidth() - mBitmap.getWidth()) / 2, (getHeight() - mBitmap.getHeight()) / 2, mDrawablePaint); } } @Override public boolean onTouchEvent(MotionEvent event) { int color; if (event.getAction() == MotionEvent.ACTION_UP) { color = mColor; } else { color = darkenColor(mColor); } mButtonPaint.setColor(color); invalidate(); return super.onTouchEvent(event); } public void show() { show(true); } public void hide() { hide(true); } public void show(boolean animate) { toggle(true, animate, false); } public void hide(boolean animate) { toggle(false, animate, false); } private void toggle(final boolean visible, final boolean animate, boolean force) { if (mHidden != visible || force) { mHidden = visible; int height = getHeight(); if (height == 0 && !force) { ViewTreeObserver vto = getViewTreeObserver(); if (vto.isAlive()) { vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { ViewTreeObserver currentVto = getViewTreeObserver(); if (currentVto.isAlive()) { currentVto.removeOnPreDrawListener(this); } toggle(visible, animate, true); return true; } }); return; } } int translationY = visible ? 0 : height + getMarginBottom(); if (animate) { animate().setInterpolator(mInterpolator) .setDuration(TRANSLATE_DURATION_MILLIS) .translationY(translationY); } else { setTranslationY(translationY); } } } public void listenTo(AbsListView listView) { if (null != listView) { mListView = listView; listView.setOnScrollListener(mOnScrollListener); } } public static int darkenColor(int color) { float[] hsv = new float[3]; Color.colorToHSV(color, hsv); hsv[2] *= 0.8f; return Color.HSVToColor(hsv); } protected int getListViewScrollY() { View topChild = mListView.getChildAt(0); return topChild == null ? 0 : mListView.getFirstVisiblePosition() * topChild.getHeight() - topChild.getTop(); } private int getMarginBottom() { int marginBottom = 0; final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams instanceof ViewGroup.MarginLayoutParams) { marginBottom = ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin; } return marginBottom; } private final AbsListView.OnScrollListener mOnScrollListener = new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { int newScrollY = getListViewScrollY(); if (newScrollY == mCurrentY) { return; } else if (newScrollY > mCurrentY && newScrollY != 0) { hide(); } else if (newScrollY < mCurrentY) { show(); } mCurrentY = newScrollY; } }; }