/** * Show this button at the specific location. If this button isn't attached to any parent view * yet, it will be add to activity's root view. If not, it will just update the location. * * @param parent The parent view. Should be {@link FrameLayout} or {@link RelativeLayout} * @param x The x value of anchor point. * @param y The y value of anchor point. * @param gravity The gravity apply with this button. * @see Gravity */ public void show(ViewGroup parent, int x, int y, int gravity) { if (getParent() == null) { ViewGroup.LayoutParams params = parent.generateLayoutParams(null); params.width = mBackground.getIntrinsicWidth(); params.height = mBackground.getIntrinsicHeight(); updateParams(x, y, gravity, params); parent.addView(this, params); } else updateLocation(x, y, gravity); }
/** * Show this button at the specific location. If this button isn't attached to any parent view * yet, it will be add to activity's root view. If not, it will just update the location. * * @param activity The activity that this button will be attached to. * @param x The x value of anchor point. * @param y The y value of anchor point. * @param gravity The gravity apply with this button. * @see Gravity */ public void show(Activity activity, int x, int y, int gravity) { if (getParent() == null) { FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( mBackground.getIntrinsicWidth(), mBackground.getIntrinsicHeight()); updateParams(x, y, gravity, params); activity.getWindow().addContentView(this, params); } else updateLocation(x, y, gravity); }
@Override public void draw(@NonNull Canvas canvas) { mBackground.draw(canvas); super.draw(canvas); if (mPrevIcon != null) mPrevIcon.draw(canvas); if (mIcon != null) mIcon.draw(canvas); }
@Override protected void drawableStateChanged() { super.drawableStateChanged(); if (mBackground != null) mBackground.setState(getDrawableState()); if (mIcon != null) mIcon.setState(getDrawableState()); if (mPrevIcon != null) mPrevIcon.setState(getDrawableState()); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public float getElevation() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return super.getElevation(); return mBackground.getShadowSize(); }
@Override public boolean onTouchEvent(@NonNull MotionEvent event) { int action = event.getActionMasked(); if (action == MotionEvent.ACTION_DOWN && !mBackground.isPointerOver(event.getX(), event.getY())) return false; boolean result = super.onTouchEvent(event); return getRippleManager().onTouchEvent(event) || result; }
private void updateParams(int x, int y, int gravity, ViewGroup.LayoutParams params) { int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; switch (horizontalGravity) { case Gravity.LEFT: setLeftMargin(params, (int) (x - mBackground.getPaddingLeft())); break; case Gravity.CENTER_HORIZONTAL: setLeftMargin(params, (int) (x - mBackground.getCenterX())); break; case Gravity.RIGHT: setLeftMargin( params, (int) (x - mBackground.getPaddingLeft() - mBackground.getRadius() * 2)); break; default: setLeftMargin(params, (int) (x - mBackground.getPaddingLeft())); break; } int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (verticalGravity) { case Gravity.TOP: setTopMargin(params, (int) (y - mBackground.getPaddingTop())); break; case Gravity.CENTER_VERTICAL: setTopMargin(params, (int) (y - mBackground.getCenterY())); break; case Gravity.BOTTOM: setTopMargin(params, (int) (y - mBackground.getPaddingTop() - mBackground.getRadius() * 2)); break; default: setTopMargin(params, (int) (y - mBackground.getPaddingTop())); break; } setLayoutParams(params); }
/** * Set the drawable that is used as this button's icon. * * @param icon The drawable. * @param animation Indicate should show animation when switch drawable or not. */ public void setIcon(Drawable icon, boolean animation) { if (icon == null) return; if (animation) { mSwitchIconAnimator.startAnimation(icon); invalidate(); } else { if (mIcon != null) { mIcon.setCallback(null); unscheduleDrawable(mIcon); } mIcon = icon; float half = mIconSize / 2f; mIcon.setBounds( (int) (mBackground.getCenterX() - half), (int) (mBackground.getCenterY() - half), (int) (mBackground.getCenterX() + half), (int) (mBackground.getCenterY() + half)); mIcon.setCallback(this); invalidate(); } }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mBackground.setBounds(0, 0, w, h); if (mIcon != null) { float half = mIconSize / 2f; mIcon.setBounds( (int) (mBackground.getCenterX() - half), (int) (mBackground.getCenterY() - half), (int) (mBackground.getCenterX() + half), (int) (mBackground.getCenterY() + half)); } if (mPrevIcon != null) { float half = mIconSize / 2f; mPrevIcon.setBounds( (int) (mBackground.getCenterX() - half), (int) (mBackground.getCenterY() - half), (int) (mBackground.getCenterX() + half), (int) (mBackground.getCenterY() + half)); } }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(mBackground.getIntrinsicWidth(), mBackground.getIntrinsicHeight()); }
/** * Set radius of the button. * * @param radius The radius in pixel. */ public void setRadius(int radius) { if (mBackground.setRadius(radius)) requestLayout(); }
@Override public void setBackgroundColor(int color) { mBackground.setColor(color); invalidate(); }
public void setBackgroundColor(ColorStateList color) { mBackground.setColor(color); invalidate(); }
/** @return The background color of this button. */ public ColorStateList getBackgroundColor() { return mBackground.getColor(); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void setElevation(float elevation) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) super.setElevation(elevation); else if (mBackground.setShadow(elevation, elevation)) requestLayout(); }
protected void applyStyle( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.FloatingActionButton, defStyleAttr, defStyleRes); int radius = -1; int elevation = -1; ColorStateList bgColor = null; int bgAnimDuration = -1; int iconSrc = 0; int iconLineMorphing = 0; for (int i = 0, count = a.getIndexCount(); i < count; i++) { int attr = a.getIndex(i); if (attr == R.styleable.FloatingActionButton_fab_radius) radius = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_elevation) elevation = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_backgroundColor) bgColor = a.getColorStateList(attr); else if (attr == R.styleable.FloatingActionButton_fab_backgroundAnimDuration) bgAnimDuration = a.getInteger(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_iconSrc) iconSrc = a.getResourceId(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_iconLineMorphing) iconLineMorphing = a.getResourceId(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_iconSize) mIconSize = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_animDuration) mAnimDuration = a.getInteger(attr, 0); else if (attr == R.styleable.FloatingActionButton_fab_interpolator) { int resId = a.getResourceId(R.styleable.FloatingActionButton_fab_interpolator, 0); if (resId != 0) mInterpolator = AnimationUtils.loadInterpolator(context, resId); } } a.recycle(); if (mIconSize < 0) mIconSize = ThemeUtil.dpToPx(context, 24); if (mAnimDuration < 0) mAnimDuration = context.getResources().getInteger(android.R.integer.config_mediumAnimTime); if (mInterpolator == null) mInterpolator = new DecelerateInterpolator(); if (mBackground == null) { if (radius < 0) radius = ThemeUtil.dpToPx(context, 28); if (elevation < 0) elevation = ThemeUtil.dpToPx(context, 4); if (bgColor == null) bgColor = ColorStateList.valueOf(ThemeUtil.colorAccent(context, 0)); if (bgAnimDuration < 0) bgAnimDuration = 0; mBackground = new OvalShadowDrawable(radius, bgColor, elevation, elevation, bgAnimDuration); mBackground.setInEditMode(isInEditMode()); mBackground.setBounds(0, 0, getWidth(), getHeight()); mBackground.setCallback(this); } else { if (radius >= 0) mBackground.setRadius(radius); if (bgColor != null) mBackground.setColor(bgColor); if (elevation >= 0) mBackground.setShadow(elevation, elevation); if (bgAnimDuration >= 0) mBackground.setAnimationDuration(bgAnimDuration); } if (iconLineMorphing != 0) setIcon(new LineMorphingDrawable.Builder(context, iconLineMorphing).build(), false); else if (iconSrc != 0) setIcon(context.getResources().getDrawable(iconSrc), false); getRippleManager().onCreate(this, context, attrs, defStyleAttr, defStyleRes); Drawable background = getBackground(); if (background != null && background instanceof RippleDrawable) { RippleDrawable drawable = (RippleDrawable) background; drawable.setBackgroundDrawable(null); drawable.setMask( RippleDrawable.Mask.TYPE_OVAL, 0, 0, 0, 0, (int) mBackground.getPaddingLeft(), (int) mBackground.getPaddingTop(), (int) mBackground.getPaddingRight(), (int) mBackground.getPaddingBottom()); } }
/** @return The radius of the button. */ public int getRadius() { return mBackground.getRadius(); }