private boolean handleRowTouch(View view, MotionEvent event) { int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mActivePointerId = event.getPointerId(0); mLastDownXlat = view.getTranslationX(); mLastDraggingView = view; mLastDownX = event.getRawX(); mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(event); int idx = mViews.indexOf(mLastDraggingView); mSpringChain.setControlSpringIndex(idx); mSpringChain.getControlSpring().setCurrentValue(mLastDownXlat); break; case MotionEvent.ACTION_MOVE: { final int pointerIndex = event.findPointerIndex(mActivePointerId); if (pointerIndex != -1) { final int location[] = {0, 0}; view.getLocationOnScreen(location); float x = event.getX(pointerIndex) + location[0]; float offset = x - mLastDownX + mLastDownXlat; mSpringChain.getControlSpring().setCurrentValue(offset); mVelocityTracker.addMovement(event); } break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: final int pointerIndex = event.findPointerIndex(mActivePointerId); if (pointerIndex != -1) { mVelocityTracker.addMovement(event); mVelocityTracker.computeCurrentVelocity(1000); mSpringChain .getControlSpring() .setVelocity(mVelocityTracker.getXVelocity()) .setEndValue(0); } break; } return true; }
public CascadeEffectExample(Context context) { super(context); LayoutInflater inflater = LayoutInflater.from(context); ViewGroup container = (ViewGroup) inflater.inflate(R.layout.cascade_effect, this, false); addView(container); ViewGroup rootView = (ViewGroup) container.findViewById(R.id.root); int bgColor = Color.argb(255, 17, 148, 231); rootView.setBackgroundColor(bgColor); int startColor = Color.argb(255, 255, 64, 230); int endColor = Color.argb(255, 255, 230, 64); ArgbEvaluator evaluator = new ArgbEvaluator(); int viewCount = 10; for (int i = 0; i < viewCount; i++) { final View view = new View(context); view.setLayoutParams( new TableLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); mSpringChain.addSpring( new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); view.setTranslationX(value); } }); int color = (Integer) evaluator.evaluate((float) i / (float) viewCount, startColor, endColor); view.setBackgroundColor(color); view.setOnTouchListener( new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return handleRowTouch(v, event); } }); mViews.add(view); rootView.addView(view); } getViewTreeObserver() .addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getViewTreeObserver().removeOnGlobalLayoutListener(this); List<Spring> springs = mSpringChain.getAllSprings(); for (int i = 0; i < springs.size(); i++) { springs.get(i).setCurrentValue(-mViews.get(i).getWidth()); } postDelayed( new Runnable() { @Override public void run() { mSpringChain.setControlSpringIndex(0).getControlSpring().setEndValue(0); } }, 500); } }); }
public class CascadeEffectExample extends FrameLayout { private final SpringChain mSpringChain = SpringChain.create(); private final List<View> mViews = new ArrayList<View>(); private float mLastDownX; /** Touch handling * */ private View mLastDraggingView; private float mLastDownXlat; private int mActivePointerId; private VelocityTracker mVelocityTracker; public CascadeEffectExample(Context context) { super(context); LayoutInflater inflater = LayoutInflater.from(context); ViewGroup container = (ViewGroup) inflater.inflate(R.layout.cascade_effect, this, false); addView(container); ViewGroup rootView = (ViewGroup) container.findViewById(R.id.root); int bgColor = Color.argb(255, 17, 148, 231); rootView.setBackgroundColor(bgColor); int startColor = Color.argb(255, 255, 64, 230); int endColor = Color.argb(255, 255, 230, 64); ArgbEvaluator evaluator = new ArgbEvaluator(); int viewCount = 10; for (int i = 0; i < viewCount; i++) { final View view = new View(context); view.setLayoutParams( new TableLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); mSpringChain.addSpring( new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); view.setTranslationX(value); } }); int color = (Integer) evaluator.evaluate((float) i / (float) viewCount, startColor, endColor); view.setBackgroundColor(color); view.setOnTouchListener( new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return handleRowTouch(v, event); } }); mViews.add(view); rootView.addView(view); } getViewTreeObserver() .addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getViewTreeObserver().removeOnGlobalLayoutListener(this); List<Spring> springs = mSpringChain.getAllSprings(); for (int i = 0; i < springs.size(); i++) { springs.get(i).setCurrentValue(-mViews.get(i).getWidth()); } postDelayed( new Runnable() { @Override public void run() { mSpringChain.setControlSpringIndex(0).getControlSpring().setEndValue(0); } }, 500); } }); } private boolean handleRowTouch(View view, MotionEvent event) { int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mActivePointerId = event.getPointerId(0); mLastDownXlat = view.getTranslationX(); mLastDraggingView = view; mLastDownX = event.getRawX(); mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(event); int idx = mViews.indexOf(mLastDraggingView); mSpringChain.setControlSpringIndex(idx); mSpringChain.getControlSpring().setCurrentValue(mLastDownXlat); break; case MotionEvent.ACTION_MOVE: { final int pointerIndex = event.findPointerIndex(mActivePointerId); if (pointerIndex != -1) { final int location[] = {0, 0}; view.getLocationOnScreen(location); float x = event.getX(pointerIndex) + location[0]; float offset = x - mLastDownX + mLastDownXlat; mSpringChain.getControlSpring().setCurrentValue(offset); mVelocityTracker.addMovement(event); } break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: final int pointerIndex = event.findPointerIndex(mActivePointerId); if (pointerIndex != -1) { mVelocityTracker.addMovement(event); mVelocityTracker.computeCurrentVelocity(1000); mSpringChain .getControlSpring() .setVelocity(mVelocityTracker.getXVelocity()) .setEndValue(0); } break; } return true; } }