/* * This file provided by Facebook is for non-commercial testing and evaluation purposes only. * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.facebook.rebound.playground.examples; import android.animation.ArgbEvaluator; import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.TableLayout; import com.facebook.rebound.SimpleSpringListener; import com.facebook.rebound.Spring; import com.facebook.rebound.SpringChain; import com.facebook.rebound.playground.R; import java.util.ArrayList; import java.util.List; public class SpringChainExample 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 SpringChainExample(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); setBackgroundColor(bgColor); rootView.setBackgroundResource(R.drawable.rebound_tiles); 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) .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; } }