diff --git a/rebound-android-playground/src/main/AndroidManifest.xml b/rebound-android-playground/src/main/AndroidManifest.xml index 488da3b..a88ad16 100644 --- a/rebound-android-playground/src/main/AndroidManifest.xml +++ b/rebound-android-playground/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ > diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/PlaygroundActivity.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/PlaygroundActivity.java index 8f27ca3..e19e3f9 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/PlaygroundActivity.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/PlaygroundActivity.java @@ -28,7 +28,8 @@ import com.facebook.rebound.SpringUtil; import com.facebook.rebound.playground.R; import com.facebook.rebound.playground.examples.BallExample; -import com.facebook.rebound.playground.examples.CascadeEffectExample; +import com.facebook.rebound.playground.examples.PhotoGalleryExample; +import com.facebook.rebound.playground.examples.SpringChainExample; import com.facebook.rebound.playground.examples.OrigamiExample; import com.facebook.rebound.playground.examples.PhotoScaleExample; @@ -43,7 +44,8 @@ public class PlaygroundActivity extends Activity implements AdapterView.OnItemCl static { SAMPLES.add(new Sample(PhotoScaleExample.class, "Photo Scale", "Scale a photo when you press and release")); - SAMPLES.add(new Sample(CascadeEffectExample.class, "Cascade Effect", "A Cascade Effect powered by a single spring")); + SAMPLES.add(new Sample(SpringChainExample.class, "SpringChain", "Drag any row in the list.")); + SAMPLES.add(new Sample(PhotoGalleryExample.class, "Photo Gallery", "Tap on a photo to enlarge or minimize.")); SAMPLES.add(new Sample(BallExample.class, "Inertia Ball", "Toss the ball around the screen and watch it settle")); SAMPLES.add(new Sample(OrigamiExample.class, "Origami Example", "Rebound port of an Origami composition")); } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/PhotoGalleryExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/PhotoGalleryExample.java new file mode 100644 index 0000000..a98830e --- /dev/null +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/PhotoGalleryExample.java @@ -0,0 +1,199 @@ +/* + * 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.content.Context; +import android.content.res.Resources; +import android.graphics.Point; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.facebook.rebound.SimpleSpringListener; +import com.facebook.rebound.Spring; +import com.facebook.rebound.SpringChain; +import com.facebook.rebound.SpringConfig; +import com.facebook.rebound.SpringListener; +import com.facebook.rebound.SpringSystem; +import com.facebook.rebound.SpringUtil; +import com.facebook.rebound.playground.app.Util; + +import java.util.ArrayList; +import java.util.List; + +public class PhotoGalleryExample extends FrameLayout implements SpringListener { + + private static final int ROWS = 5; + private static final int COLS = 4; + + private final List mImageViews = new ArrayList(); + private final List mPositions = new ArrayList(); + private final SpringChain mSpringChain = SpringChain.create(); + private final Spring mSpring = SpringSystem + .create() + .createSpring() + .addListener(this) + .setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(30, 6)); + + private int mActiveIndex; + private int mPadding; + + public PhotoGalleryExample(Context context) { + super(context); + + int viewCount = ROWS * COLS; + + for (int i = 0; i < viewCount; i++) { + final int j = i; + + // Create the View. + final ImageView imageView = new ImageView(context); + mImageViews.add(imageView); + addView(imageView); + imageView.setAlpha(0f); + imageView.setBackgroundColor(Util.randomColor()); + imageView.setLayerType(LAYER_TYPE_HARDWARE, null); + + // Add an image for each view. + int res = getResources().getIdentifier("d" + (i % 11 + 1), "drawable", context.getPackageName()); + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + imageView.setImageResource(res); + + // Add a click listener to handle scaling up the view. + imageView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + int endValue = mSpring.getEndValue() == 0 ? 1 : 0; + imageView.bringToFront(); + mActiveIndex = j; + mSpring.setEndValue(endValue); + } + }); + + // Add a spring to the SpringChain to do an entry animation. + mSpringChain.addSpring(new SimpleSpringListener() { + @Override + public void onSpringUpdate(Spring spring) { + render(); + } + }); + } + + // Wait for layout. + getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + layout(); + getViewTreeObserver().removeOnGlobalLayoutListener(this); + + postOnAnimationDelayed(new Runnable() { + @Override + public void run() { + mSpringChain.setControlSpringIndex(0).getControlSpring().setEndValue(1); + } + }, 500); + } + }); + + } + + private void render() { + for (int i = 0; i < mImageViews.size(); i++) { + ImageView imageView = mImageViews.get(i); + if (mSpring.isAtRest() && mSpring.getCurrentValue() == 0) { + // Performing the initial entry transition animation. + Spring spring = mSpringChain.getAllSprings().get(i); + float val = (float) spring.getCurrentValue(); + imageView.setScaleX(val); + imageView.setScaleY(val); + imageView.setAlpha(val); + Point pos = mPositions.get(i); + imageView.setTranslationX(pos.x); + imageView.setTranslationY(pos.y); + } else { + // Scaling up a photo to fullscreen size. + Point pos = mPositions.get(i); + if (i == mActiveIndex) { + float ww = imageView.getWidth(); + float hh = imageView.getHeight(); + float sx = getWidth() / ww; + float sy = getHeight() / hh; + float s = sx > sy ? sx : sy; + float xlatX = (float) SpringUtil.mapValueFromRangeToRange(mSpring.getCurrentValue(), 0, 1, pos.x, 0); + float xlatY = (float) SpringUtil.mapValueFromRangeToRange(mSpring.getCurrentValue(), 0, 1, pos.y, 0); + imageView.setPivotX(0); + imageView.setPivotY(0); + imageView.setTranslationX(xlatX); + imageView.setTranslationY(xlatY); + + float ss = (float) SpringUtil.mapValueFromRangeToRange(mSpring.getCurrentValue(), 0, 1, 1, s); + imageView.setScaleX(ss); + imageView.setScaleY(ss); + } else { + float val = (float) Math.max(0, 1 - mSpring.getCurrentValue()); + imageView.setAlpha(val); + } + } + } + } + + private void layout() { + float width = getWidth(); + float height = getHeight(); + + // Determine the size for each image given the screen dimensions. + Resources res = getResources(); + mPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, res.getDisplayMetrics()); + int colWidth = (int) Math.ceil((width - 2 * mPadding) / COLS) - 2 * mPadding; + int rowHeight = (int) Math.ceil((height - 2 * mPadding) / ROWS) - 2 * mPadding; + + // Determine the resting position for each view. + int k = 0; + int py = 0; + for (int i = 0; i < ROWS; i++) { + int px = 0; + py += mPadding * 2; + for (int j = 0; j < COLS; j++) { + px += mPadding * 2; + ImageView imageView = mImageViews.get(k); + imageView.setLayoutParams(new LayoutParams(colWidth, rowHeight)); + mPositions.add(new Point(px, py)); + px += colWidth; + k++; + } + py += rowHeight; + } + } + + @Override + public void onSpringUpdate(Spring spring) { + render(); + } + + @Override + public void onSpringAtRest(Spring spring) { + + } + + @Override + public void onSpringActivate(Spring spring) { + + } + + @Override + public void onSpringEndStateChange(Spring spring) { + + } +} diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/CascadeEffectExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java similarity index 96% rename from rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/CascadeEffectExample.java rename to rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java index 0d0d3a4..12aee48 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/CascadeEffectExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java @@ -32,7 +32,7 @@ import java.util.ArrayList; import java.util.List; -public class CascadeEffectExample extends FrameLayout { +public class SpringChainExample extends FrameLayout { private final SpringChain mSpringChain = SpringChain.create(); @@ -45,7 +45,7 @@ public class CascadeEffectExample extends FrameLayout { private int mActivePointerId; private VelocityTracker mVelocityTracker; - public CascadeEffectExample(Context context) { + public SpringChainExample(Context context) { super(context); LayoutInflater inflater = LayoutInflater.from(context); @@ -53,7 +53,8 @@ public CascadeEffectExample(Context context) { addView(container); ViewGroup rootView = (ViewGroup) container.findViewById(R.id.root); int bgColor = Color.argb(255, 17, 148, 231); - rootView.setBackgroundColor(bgColor); + setBackgroundColor(bgColor); + rootView.setBackgroundResource(R.drawable.rebound_tiles); int startColor = Color.argb(255, 255, 64, 230); int endColor = Color.argb(255, 255, 230, 64); diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d1.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d1.jpg new file mode 100644 index 0000000..e195c33 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d1.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d10.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d10.jpg new file mode 100644 index 0000000..e41227b Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d10.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d11.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d11.jpg new file mode 100644 index 0000000..2f1d520 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d11.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d12.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d12.jpg new file mode 100644 index 0000000..fe3b3c0 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d12.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d2.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d2.jpg new file mode 100644 index 0000000..8e4f383 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d2.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d3.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d3.jpg new file mode 100644 index 0000000..fa78047 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d3.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d4.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d4.jpg new file mode 100644 index 0000000..8960c1b Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d4.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d5.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d5.jpg new file mode 100644 index 0000000..d26a382 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d5.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d6.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d6.jpg new file mode 100644 index 0000000..6f990b8 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d6.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d7.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d7.jpg new file mode 100644 index 0000000..ded1724 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d7.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d8.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d8.jpg new file mode 100644 index 0000000..3ad4054 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d8.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable-nodpi/d9.jpg b/rebound-android-playground/src/main/res/drawable-nodpi/d9.jpg new file mode 100644 index 0000000..e664b16 Binary files /dev/null and b/rebound-android-playground/src/main/res/drawable-nodpi/d9.jpg differ diff --git a/rebound-android-playground/src/main/res/drawable/rebound_tiles.xml b/rebound-android-playground/src/main/res/drawable/rebound_tiles.xml new file mode 100644 index 0000000..d556425 --- /dev/null +++ b/rebound-android-playground/src/main/res/drawable/rebound_tiles.xml @@ -0,0 +1,7 @@ + + +