Ripples using Probe and RevealColorViews
package com.cafesalam.experiments.app.ui; | |
import org.lucasr.probe.Interceptor; | |
import android.content.Context; | |
import android.graphics.Color; | |
import android.graphics.Point; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.ViewParent; | |
import android.widget.FrameLayout; | |
import java.util.WeakHashMap; | |
import at.markushi.ui.RevealColorView; | |
/* this class is a Probe Interceptor that gives views a ripple effect | |
* using https://github.com/markushi/android-ui. | |
* | |
* based on markus's sample gist: | |
* https://gist.github.com/markushi/68ce8df77bed164b6275 | |
*/ | |
public class RevealInterceptor extends Interceptor { | |
private static final int BACKGROUND = Color.parseColor("#212121"); | |
private Context mContext; | |
private WeakHashMap<View, FrameLayout> mMapping; | |
public RevealInterceptor(Context context) { | |
mContext = context; | |
mMapping = new WeakHashMap<>(); | |
} | |
@Override | |
public void onLayout(View view, boolean changed, | |
int left, int top, int right, int bottom) { | |
if (!(view instanceof ViewGroup)) { | |
FrameLayout container = mMapping.get(view); | |
if (container == null) { | |
container = new FrameLayout(mContext); | |
mMapping.put(view, container); | |
RevealColorView revealColorView = new RevealColorView(mContext); | |
revealColorView.setBackgroundColor(BACKGROUND); | |
final ViewParent parent = view.getParent(); | |
if (parent instanceof ViewGroup) { | |
final ViewGroup pvg = (ViewGroup) parent; | |
final int index = pvg.indexOfChild(view); | |
pvg.removeViewInLayout(view); | |
// you'd perhaps set this in xml as per android-ui's gist | |
view.setTag(new Holder("#8bc34a")); | |
container.addView(revealColorView); | |
container.addView(view); | |
// ideally should use addViewInLayout, but can't because | |
// it is protected | |
pvg.addView(container, index, view.getLayoutParams()); | |
pvg.invalidate(); | |
view.setOnClickListener(mOnClickListener); | |
} | |
} | |
} | |
super.onLayout(view, changed, left, top, right, bottom); | |
} | |
private static class Holder { | |
public int color; | |
public boolean isShowing; | |
public Holder(String colorStr) { | |
this.color = Color.parseColor(colorStr); | |
} | |
} | |
private View.OnClickListener mOnClickListener = new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
final RevealColorView revealColorView = | |
(RevealColorView) (((ViewGroup) v.getParent()).getChildAt(0)); | |
final Point p = getLocationInView(revealColorView, v); | |
final Holder holder = (Holder) v.getTag(); | |
final int color = holder.color; | |
if (holder.isShowing) { | |
revealColorView.hide(p.x, p.y, BACKGROUND, 0, 300, null); | |
holder.isShowing = false; | |
} else { | |
revealColorView.reveal(p.x, p.y, color, v.getHeight() / 2, 340, null); | |
holder.isShowing = true; | |
} | |
} | |
}; | |
private Point getLocationInView(View src, View target) { | |
final int[] l0 = new int[2]; | |
src.getLocationOnScreen(l0); | |
final int[] l1 = new int[2]; | |
target.getLocationOnScreen(l1); | |
l1[0] = l1[0] - l0[0] + target.getWidth() / 2; | |
l1[1] = l1[1] - l0[1] + target.getHeight() / 2; | |
return new Point(l1[0], l1[1]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
updated per Lucas's comments - use
removeViewInLayout
instead ofremoveViewAt
, and add a comment aboutaddViewInLayout
.