public RippleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); }
/** * Method that initializes all fields and sets listeners * * @param context Context used to create this view * @param attrs Attribute used to initialize fields */ private void init(final Context context, final AttributeSet attrs) { if (isInEditMode()) return;
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); WIDTH = w; HEIGHT = h;
scaleAnimation = new ScaleAnimation(1.0f, zoomScale, 1.0f, zoomScale, w / 2, h / 2); scaleAnimation.setDuration(zoomDuration); scaleAnimation.setRepeatMode(Animation.REVERSE); scaleAnimation.setRepeatCount(1); }
/** * Launch Ripple animation for the current view with a MotionEvent * * @param event MotionEvent registered by the Ripple gesture listener */ public void animateRipple(MotionEvent event) { createAnimation(event.getX(), event.getY()); }
/** * Launch Ripple animation for the current view centered at x and y position * * @param x Horizontal position of the ripple center * @param y Vertical position of the ripple center */ public void animateRipple(final float x, final float y) { createAnimation(x, y); }
/** * Create Ripple animation centered at x, y * * @param x Horizontal position of the ripple center * @param y Vertical position of the ripple center */ private void createAnimation(final float x, final float y) { if (this.isEnabled() && !animationRunning) { if (hasToZoom) this.startAnimation(scaleAnimation);
@Override public boolean onTouchEvent(MotionEvent event) { if (gestureDetector.onTouchEvent(event)) { animateRipple(event); sendClickEvent(false); } return super.onTouchEvent(event); }
@Override public boolean onInterceptTouchEvent(MotionEvent event) { this.onTouchEvent(event); return super.onInterceptTouchEvent(event); }
/** * Send a click event if parent view is a Listview instance * * @param isLongClick Is the event a long click ? */ private void sendClickEvent(final Boolean isLongClick) { if (getParent() instanceof AdapterView) { final AdapterView adapterView = (AdapterView) getParent(); final int position = adapterView.getPositionForView(this); final long id = adapterView.getItemIdAtPosition(position); if (isLongClick) { if (adapterView.getOnItemLongClickListener() != null) adapterView.getOnItemLongClickListener().onItemLongClick(adapterView, this, position, id); } else { if (adapterView.getOnItemClickListener() != null) adapterView.getOnItemClickListener().onItemClick(adapterView, this, position, id); } } }
private Bitmap getCircleBitmap(final int radius) { final Bitmap output = Bitmap.createBitmap(originBitmap.getWidth(), originBitmap.getHeight(), Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect((int)(x - radius), (int)(y - radius), (int)(x + radius), (int)(y + radius));
paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); canvas.drawCircle(x, y, radius, paint);
/** * Set Ripple color, default is #FFFFFF * * @param rippleColor New color resource */ @ColorRes public void setRippleColor(int rippleColor) { this.rippleColor = getResources().getColor(rippleColor); }
public int getRippleColor() { return rippleColor; }
public RippleType getRippleType() { return RippleType.values()[rippleType]; }
/** * Set Ripple type, default is RippleType.SIMPLE * * @param rippleType New Ripple type for next animation */ public void setRippleType(final RippleType rippleType) { this.rippleType = rippleType.ordinal(); }
public Boolean isCentered() { return isCentered; }
/** * Set if ripple animation has to be centered in its parent view or not, default is False * * @param isCentered */ public void setCentered(final Boolean isCentered) { this.isCentered = isCentered; }
public int getRipplePadding() { return ripplePadding; }
/** * Set Ripple padding if you want to avoid some graphic glitch * * @param ripplePadding New Ripple padding in pixel, default is 0px */ public void setRipplePadding(int ripplePadding) { this.ripplePadding = ripplePadding; }
public Boolean isZooming() { return hasToZoom; }
/** * At the end of Ripple effect, the child views has to zoom * * @param hasToZoom Do the child views have to zoom ? default is False */ public void setZooming(Boolean hasToZoom) { this.hasToZoom = hasToZoom; }
public float getZoomScale() { return zoomScale; }
/** * Scale of the end animation * * @param zoomScale Value of scale animation, default is 1.03f */ public void setZoomScale(float zoomScale) { this.zoomScale = zoomScale; }
public int getZoomDuration() { return zoomDuration; }
/** * Duration of the ending animation in ms * * @param zoomDuration Duration, default is 200ms */ public void setZoomDuration(int zoomDuration) { this.zoomDuration = zoomDuration; }
public int getRippleDuration() { return rippleDuration; }
/** * Duration of the Ripple animation in ms * * @param rippleDuration Duration, default is 400ms */ public void setRippleDuration(int rippleDuration) { this.rippleDuration = rippleDuration; }
public int getFrameRate() { return frameRate; }
/** * Set framerate for Ripple animation * * @param frameRate New framerate value, default is 10 */ public void setFrameRate(int frameRate) { this.frameRate = frameRate; }
public int getRippleAlpha() { return rippleAlpha; }
/** * Set alpha for ripple effect color * * @param rippleAlpha Alpha value between 0 and 255, default is 90 */ public void setRippleAlpha(int rippleAlpha) { this.rippleAlpha = rippleAlpha; }
public void setOnRippleCompleteListener(OnRippleCompleteListener listener) { this.onCompletionListener = listener; }
/** * Defines a callback called at the end of the Ripple effect */ public interface OnRippleCompleteListener { void onComplete(RippleView rippleView); }
public enum RippleType { SIMPLE(0), DOUBLE(1), RECTANGLE(2);