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); } }); }