Last active
January 18, 2016 00:26
-
-
Save boxcounter/89fe6c3de997ac6dd473 to your computer and use it in GitHub Desktop.
add ripple effect to SimpleDraweeView
This file contains 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
package com.unnoo.quan.views; | |
import android.annotation.TargetApi; | |
import android.content.Context; | |
import android.content.res.TypedArray; | |
import android.graphics.Canvas; | |
import android.graphics.Rect; | |
import android.graphics.drawable.Drawable; | |
import android.os.Build; | |
import android.util.AttributeSet; | |
import android.view.Gravity; | |
import com.facebook.drawee.generic.GenericDraweeHierarchy; | |
import com.facebook.drawee.view.SimpleDraweeView; | |
import com.unnoo.quan.R; | |
/** | |
* DraweeView with ripple effect | |
* Refer:https://gist.github.com/chrisbanes/9091754 | |
*/ | |
public class ForegroundImageView extends SimpleDraweeView { | |
private Drawable mForeground; | |
private final Rect mSelfBounds = new Rect(); | |
private final Rect mOverlayBounds = new Rect(); | |
private int mForegroundGravity = Gravity.FILL; | |
protected boolean mForegroundInPadding = true; | |
boolean mForegroundBoundsChanged = false; | |
public ForegroundImageView(Context context, GenericDraweeHierarchy hierarchy) { | |
super(context, hierarchy); | |
initialize(context, null, 0); | |
} | |
public ForegroundImageView(Context context) { | |
super(context); | |
initialize(context, null, 0); | |
} | |
public ForegroundImageView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
initialize(context, attrs, 0); | |
} | |
public ForegroundImageView(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
initialize(context, attrs, defStyle); | |
} | |
private void initialize(Context context, AttributeSet attrs, int defStyle) { | |
if (null == attrs) return; | |
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundImageView, defStyle, 0); | |
mForegroundGravity = a.getInt( | |
R.styleable.ForegroundImageView_foregroundGravity, mForegroundGravity); | |
final Drawable d = a.getDrawable(R.styleable.ForegroundImageView_foreground); | |
if (d != null) { | |
setForeground(d); | |
} | |
mForegroundInPadding = a.getBoolean( | |
R.styleable.ForegroundImageView_foregroundInsidePadding, true); | |
a.recycle(); | |
} | |
/** | |
* Describes how the foreground is positioned. | |
* | |
* @return foreground gravity. | |
* | |
* @see #setForegroundGravity(int) | |
*/ | |
public int getForegroundGravity() { | |
return mForegroundGravity; | |
} | |
/** | |
* Describes how the foreground is positioned. Defaults to START and TOP. | |
* | |
* @param foregroundGravity See {@link android.view.Gravity} | |
* | |
* @see #getForegroundGravity() | |
*/ | |
public void setForegroundGravity(int foregroundGravity) { | |
if (mForegroundGravity != foregroundGravity) { | |
if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) { | |
foregroundGravity |= Gravity.START; | |
} | |
if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) { | |
foregroundGravity |= Gravity.TOP; | |
} | |
mForegroundGravity = foregroundGravity; | |
if (mForegroundGravity == Gravity.FILL && mForeground != null) { | |
Rect padding = new Rect(); | |
mForeground.getPadding(padding); | |
} | |
requestLayout(); | |
} | |
} | |
@Override | |
protected boolean verifyDrawable(Drawable who) { | |
return super.verifyDrawable(who) || (who == mForeground); | |
} | |
@Override | |
public void jumpDrawablesToCurrentState() { | |
super.jumpDrawablesToCurrentState(); | |
if (mForeground != null) mForeground.jumpToCurrentState(); | |
} | |
@Override | |
protected void drawableStateChanged() { | |
super.drawableStateChanged(); | |
if (mForeground != null && mForeground.isStateful()) { | |
mForeground.setState(getDrawableState()); | |
} | |
} | |
/** | |
* Supply a Drawable that is to be rendered on top of all of the child | |
* views in the frame layout. Any padding in the Drawable will be taken | |
* into account by ensuring that the children are inset to be placed | |
* inside of the padding area. | |
* | |
* @param drawable The Drawable to be drawn on top of the children. | |
*/ | |
public void setForeground(Drawable drawable) { | |
if (mForeground != drawable) { | |
if (mForeground != null) { | |
mForeground.setCallback(null); | |
unscheduleDrawable(mForeground); | |
} | |
mForeground = drawable; | |
if (drawable != null) { | |
setWillNotDraw(false); | |
drawable.setCallback(this); | |
if (drawable.isStateful()) { | |
drawable.setState(getDrawableState()); | |
} | |
if (mForegroundGravity == Gravity.FILL) { | |
Rect padding = new Rect(); | |
drawable.getPadding(padding); | |
} | |
} else { | |
setWillNotDraw(true); | |
} | |
requestLayout(); | |
invalidate(); | |
} | |
} | |
/** | |
* Returns the drawable used as the foreground of this FrameLayout. The | |
* foreground drawable, if non-null, is always drawn on top of the children. | |
* | |
* @return A Drawable or null if no foreground was set. | |
*/ | |
public Drawable getForeground() { | |
return mForeground; | |
} | |
@Override | |
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
super.onLayout(changed, left, top, right, bottom); | |
mForegroundBoundsChanged = changed; | |
} | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
super.onSizeChanged(w, h, oldw, oldh); | |
mForegroundBoundsChanged = true; | |
} | |
@Override | |
public void draw(Canvas canvas) { | |
super.draw(canvas); | |
if (mForeground != null) { | |
final Drawable foreground = mForeground; | |
if (mForegroundBoundsChanged) { | |
mForegroundBoundsChanged = false; | |
final Rect selfBounds = mSelfBounds; | |
final Rect overlayBounds = mOverlayBounds; | |
final int w = getRight() - getLeft(); | |
final int h = getBottom() - getTop(); | |
if (mForegroundInPadding) { | |
selfBounds.set(0, 0, w, h); | |
} else { | |
selfBounds.set(getPaddingLeft(), getPaddingTop(), | |
w - getPaddingRight(), h - getPaddingBottom()); | |
} | |
Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(), | |
foreground.getIntrinsicHeight(), selfBounds, overlayBounds); | |
foreground.setBounds(overlayBounds); | |
} | |
foreground.draw(canvas); | |
} | |
} | |
@TargetApi(Build.VERSION_CODES.LOLLIPOP) | |
@Override | |
public void drawableHotspotChanged(float x, float y) { | |
super.drawableHotspotChanged(x, y); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
if (mForeground != null) { | |
mForeground.setHotspot(x, y); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment