From 2ba347eb318b6b5b9fabcc47f815927915864d85 Mon Sep 17 00:00:00 2001 From: Pedro Paulo de Amorim Date: Sun, 28 Jun 2015 02:20:04 -0300 Subject: [PATCH 1/6] Changes on examples A better code structure and API downgraded to 14 --- rebound-android-playground/build.gradle | 2 +- .../playground/examples/BallExample.java | 165 +++++++++--------- .../playground/examples/OrigamiExample.java | 18 +- .../examples/PhotoGalleryExample.java | 92 +++++----- .../playground/examples/SimpleExample.java | 13 +- .../examples/SpringChainExample.java | 71 ++++---- 6 files changed, 165 insertions(+), 196 deletions(-) diff --git a/rebound-android-playground/build.gradle b/rebound-android-playground/build.gradle index 3274b37..11a3d2a 100644 --- a/rebound-android-playground/build.gradle +++ b/rebound-android-playground/build.gradle @@ -14,7 +14,7 @@ android { applicationId "com.facebook.rebound.androidplayground" versionCode Integer.parseInt(project.VERSION_CODE) versionName project.VERSION_NAME - minSdkVersion 19 + minSdkVersion 14 targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION) } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/BallExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/BallExample.java index dbab37a..02a738a 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/BallExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/BallExample.java @@ -37,13 +37,13 @@ public class BallExample extends FrameLayout implements SpringListener, SpringSystemListener { - private final Spring xSpring; - private final Spring ySpring; - private final SpringSystem springSystem; - private final SpringConfig COASTING; + private static final String TEXT = "TOUCH"; + + private Spring xSpring; + private Spring ySpring; + private SpringConfig COASTING; private float x; private float y; - private Paint paint; private boolean dragging; private float radius = 100; private float downX; @@ -55,10 +55,20 @@ public class BallExample extends FrameLayout implements SpringListener, SpringSy private float centerY; private float attractionThreshold = 200; private SpringConfig CONVERGING = SpringConfig.fromOrigamiTensionAndFriction(20, 3); - private List points = new ArrayList(); + private List points = new ArrayList<>(); private ArgbEvaluator colorEvaluator = new ArgbEvaluator(); private Integer startColor = Color.argb(255, 0, 255, 48); private Integer endColor = Color.argb(255, 0, 228, 255); + private Integer background = Color.argb(255, 240, 240, 240); + + private int i = 0; + + private float touchX; + private float touchY; + + private Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint ballPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public BallExample(Context context) { this(context, null); @@ -70,75 +80,48 @@ public BallExample(Context context, AttributeSet attrs) { public BallExample(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - COASTING = SpringConfig.fromOrigamiTensionAndFriction(0, 0.5); - COASTING.tension = 0; setBackgroundColor(Color.WHITE); + configCoasing(); + configCirclePaint(); + configBallPaint(); + configTextPaint(); + } - springSystem = SpringSystem.create(); - springSystem.addListener(this); - xSpring = springSystem.createSpring(); - ySpring = springSystem.createSpring(); - xSpring.addListener(this); - ySpring.addListener(this); - paint = new Paint(Paint.ANTI_ALIAS_FLAG); - - getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - centerX = getWidth() / 2f; - centerY = getHeight() / 2f; - - xSpring.setCurrentValue(centerX).setAtRest(); - ySpring.setCurrentValue(centerY).setAtRest(); - getViewTreeObserver().removeOnGlobalLayoutListener(this); - - int offsetH = (int) ((getHeight() - (2 * radius)) % 800) / 2; - int offsetW = (int) ((getWidth() - (2 * radius)) % 800) / 2; - for (float i = offsetH + radius; i < getHeight() - offsetH; i += 400) { - for (float j = offsetW + radius; j < getWidth() - offsetW; j += 400) { - points.add(new PointF(j, i)); - } - } + @Override protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { + super.onSizeChanged(width, height, oldWidth, oldHeight); + centerX = getWidth() / 2f; + centerY = getHeight() / 2f; + xSpring.setCurrentValue(centerX).setAtRest(); + ySpring.setCurrentValue(centerY).setAtRest(); + int offsetH = (int) ((getHeight() - (2 * radius)) % 800) / 2; + int offsetW = (int) ((getWidth() - (2 * radius)) % 800) / 2; + for (float i = offsetH + radius; i < getHeight() - offsetH; i += 400) { + for (float j = offsetW + radius; j < getWidth() - offsetW; j += 400) { + points.add(new PointF(j, i)); } - }); + } } - @Override - protected void onDraw(Canvas canvas) { + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - - int bg = Color.argb(255, 240, 240, 240); - canvas.drawColor(bg); - - int i = 0; + canvas.drawColor(background); + i = 0; for (PointF point : points) { - paint.setColor(Color.argb(255, 255, 255, 255)); - paint.setStyle(Paint.Style.FILL); - canvas.drawCircle(point.x, point.y, attractionThreshold - 80, paint); - Integer color = (Integer) colorEvaluator.evaluate( - (i + 1) / (float) points.size(), startColor, endColor); - paint.setColor(color); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(20); - canvas.drawCircle(point.x, point.y, attractionThreshold - 80, paint); + canvas.drawCircle(point.x, point.y, attractionThreshold - 80, circlePaint); + circlePaint.setColor( + (Integer) colorEvaluator.evaluate((i + 1) / (float) points.size(), startColor, endColor)); + circlePaint.setStyle(Paint.Style.STROKE); + canvas.drawCircle(point.x, point.y, attractionThreshold - 80, circlePaint); i++; } - - paint.setColor(Color.argb(200, 255, 0, 0)); - paint.setStyle(Paint.Style.FILL); - canvas.drawCircle(x, y, radius, paint); - paint.setColor(Color.WHITE); - paint.setTextSize(36); - paint.setTextAlign(Paint.Align.CENTER); - canvas.drawText("TOUCH", x, y + 10, paint); + canvas.drawCircle(x, y, radius, ballPaint); + canvas.drawText(TEXT, x, y + 10, textPaint); } - @Override - public boolean onTouchEvent(MotionEvent event) { - float touchX = event.getRawX(); - float touchY = event.getRawY(); + @Override public boolean onTouchEvent(MotionEvent event) { + touchX = event.getRawX(); + touchY = event.getRawY(); boolean ret = false; - switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = touchX; @@ -180,40 +163,26 @@ public boolean onTouchEvent(MotionEvent event) { ySpring.setVelocity(velocityTracker.getYVelocity()); ret = true; } - lastX = touchX; lastY = touchY; return ret; } - @Override - public void onSpringUpdate(Spring spring) { + @Override public void onSpringUpdate(Spring spring) { x = (float) xSpring.getCurrentValue(); y = (float) ySpring.getCurrentValue(); invalidate(); } - @Override - public void onSpringAtRest(Spring spring) { + @Override public void onSpringAtRest(Spring spring) { } - } + @Override public void onSpringActivate(Spring spring) { } - @Override - public void onSpringActivate(Spring spring) { - - } + @Override public void onSpringEndStateChange(Spring spring) { } - @Override - public void onSpringEndStateChange(Spring spring) { + @Override public void onBeforeIntegrate(BaseSpringSystem springSystem) { } - } - - @Override - public void onBeforeIntegrate(BaseSpringSystem springSystem) { - } - - @Override - public void onAfterIntegrate(BaseSpringSystem springSystem) { + @Override public void onAfterIntegrate(BaseSpringSystem springSystem) { checkConstraints(); } @@ -234,7 +203,6 @@ private void checkConstraints() { ySpring.setVelocity(-ySpring.getVelocity()); ySpring.setCurrentValue(ySpring.getCurrentValue() - (y - radius), false); } - for (PointF point : points) { if (dist(x, y, point.x, point.y) < attractionThreshold && Math.abs(xSpring.getVelocity()) < 900 && @@ -248,7 +216,36 @@ private void checkConstraints() { } } + private void configCirclePaint() { + circlePaint.setColor(Color.argb(255, 255, 255, 255)); + circlePaint.setStyle(Paint.Style.FILL); + circlePaint.setStrokeWidth(20); + } + + private void configTextPaint() { + textPaint.setColor(Color.WHITE); + textPaint.setTextSize(36); + textPaint.setTextAlign(Paint.Align.CENTER); + } + + private void configBallPaint() { + ballPaint.setColor(Color.argb(200, 255, 0, 0)); + ballPaint.setStyle(Paint.Style.FILL); + } + + private void configCoasing() { + COASTING = SpringConfig.fromOrigamiTensionAndFriction(0, 0.5); + COASTING.tension = 0; + SpringSystem springSystem = SpringSystem.create(); + springSystem.addListener(this); + xSpring = springSystem.createSpring(); + ySpring = springSystem.createSpring(); + xSpring.addListener(this); + ySpring.addListener(this); + } + private float dist(double posX, double posY, double pos2X, double pos2Y) { return (float) Math.sqrt(Math.pow(pos2X - posX, 2) + Math.pow(pos2Y - posY, 2)); } + } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/OrigamiExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/OrigamiExample.java index bb068a3..9a77311 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/OrigamiExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/OrigamiExample.java @@ -6,7 +6,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.ViewTreeObserver; import android.widget.FrameLayout; import com.facebook.rebound.SimpleSpringListener; @@ -74,18 +73,6 @@ public void onSpringUpdate(Spring spring) { } }); - - // Here we just wait until the first layout pass finishes and call our render method to update - // the animation to the initial resting state of the spring. - mPhotoGrid.getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - render(); - mPhotoGrid.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } - }); - /** Optional - Live Spring Tuning **/ // Put our config into a registry. This is optional, but it gives you the ability to live tune @@ -99,6 +86,11 @@ public void onGlobalLayout() { mSpringConfiguratorView.setVisibility(View.VISIBLE); } + @Override protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { + super.onSizeChanged(width, height, oldWidth, oldHeight); + render(); + } + /** * On click we just move the springs end state from 0 to 1. This allows the Spring to act much * like an Origami switch. 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 index 6fb8f1d..b62f7bb 100644 --- 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 @@ -38,8 +38,8 @@ 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 List mImageViews = new ArrayList<>(); + private final List mPositions = new ArrayList<>(); private final SpringChain mSpringChain = SpringChain.create(); private final Spring mSpring = SpringSystem .create() @@ -52,14 +52,29 @@ public class PhotoGalleryExample extends FrameLayout implements SpringListener { public PhotoGalleryExample(Context context) { super(context); + initializeImageViews(context); - int viewCount = ROWS * COLS; + // 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); + } + }); - for (int i = 0; i < viewCount; i++) { - final int j = i; + } + private void initializeImageViews(Context context) { + int viewCount = ROWS * COLS; + for (int i = 0; i < viewCount; i++) { // Create the View. - final ImageView imageView = new ImageView(context); + ImageView imageView = new ImageView(context); mImageViews.add(imageView); addView(imageView); imageView.setAlpha(0f); @@ -67,46 +82,17 @@ public PhotoGalleryExample(Context context) { 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); + imageView.setImageResource(getResources().getIdentifier("d" + (i % 11 + 1), + "drawable", context.getPackageName())); + imageView.setTag(i); // 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); - } - }); + imageView.setOnClickListener(onImageClick); // Add a spring to the SpringChain to do an entry animation. - mSpringChain.addSpring(new SimpleSpringListener() { - @Override - public void onSpringUpdate(Spring spring) { - render(); - } - }); + mSpringChain.addSpring(this); } - - // 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() { @@ -177,23 +163,25 @@ private void layout() { } } - @Override - public void onSpringUpdate(Spring spring) { + @Override public void onSpringUpdate(Spring spring) { render(); } - @Override - public void onSpringAtRest(Spring spring) { - - } + @Override public void onSpringAtRest(Spring spring) { } - @Override - public void onSpringActivate(Spring spring) { + @Override public void onSpringActivate(Spring spring) { } - } + @Override public void onSpringEndStateChange(Spring spring) { } - @Override - public void onSpringEndStateChange(Spring spring) { + private View.OnClickListener onImageClick = new OnClickListener() { + @Override public void onClick(View v) { + Object tag = v.getTag(); + if(tag instanceof Integer) { + mImageViews.get((Integer) tag).bringToFront(); + mActiveIndex = (Integer) tag; + mSpring.setEndValue(mSpring.getEndValue() == 0 ? 1 : 0); + } + } + }; - } } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SimpleExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SimpleExample.java index 3b65ea5..fc016f0 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SimpleExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SimpleExample.java @@ -22,7 +22,6 @@ import com.facebook.rebound.BaseSpringSystem; import com.facebook.rebound.SimpleSpringListener; import com.facebook.rebound.Spring; -import com.facebook.rebound.SpringConfig; import com.facebook.rebound.SpringSystem; import com.facebook.rebound.SpringUtil; import com.facebook.rebound.playground.R; @@ -67,22 +66,22 @@ public boolean onTouch(View v, MotionEvent event) { addView(mRootView); } - @Override - protected void onAttachedToWindow() { + @Override protected void onAttachedToWindow() { + super.onAttachedToWindow(); mScaleSpring.addListener(mSpringListener); } - @Override - protected void onDetachedFromWindow() { + @Override protected void onDetachedFromWindow() { mScaleSpring.removeListener(mSpringListener); + super.onDetachedFromWindow(); } private class ExampleSpringListener extends SimpleSpringListener { - @Override - public void onSpringUpdate(Spring spring) { + @Override public void onSpringUpdate(Spring spring) { float mappedValue = (float) SpringUtil.mapValueFromRangeToRange(spring.getCurrentValue(), 0, 1, 1, 0.5); mImageView.setScaleX(mappedValue); mImageView.setScaleY(mappedValue); } } + } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java index 12aee48..1c313d0 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringChainExample.java @@ -20,7 +20,6 @@ import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; -import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.TableLayout; @@ -36,29 +35,42 @@ public class SpringChainExample extends FrameLayout { private final SpringChain mSpringChain = SpringChain.create(); - private final List mViews = new ArrayList(); + private final List mViews = new ArrayList<>(); private float mLastDownX; /** Touch handling **/ - private View mLastDraggingView; private float mLastDownXlat; private int mActivePointerId; private VelocityTracker mVelocityTracker; + private Integer startColor = Color.argb(255, 255, 64, 230); + private Integer endColor = Color.argb(255, 255, 230, 64); + public SpringChainExample(Context context) { super(context); - + setBackgroundColor(Color.argb(255, 17, 148, 231)); 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); + initializeViews(context, rootView, new ArgbEvaluator()); + } + + @Override protected void onFinishInflate() { + super.onFinishInflate(); + List 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); + } - int startColor = Color.argb(255, 255, 64, 230); - int endColor = Color.argb(255, 255, 230, 64); - ArgbEvaluator evaluator = new ArgbEvaluator(); + private void initializeViews(Context context, ViewGroup rootView, ArgbEvaluator evaluator) { int viewCount = 10; for (int i = 0; i < viewCount; i++) { final View view = new View(context); @@ -74,37 +86,12 @@ public void onSpringUpdate(Spring spring) { 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); - } - }); + view.setBackgroundColor((Integer) + evaluator.evaluate((float) i / (float) viewCount, startColor, endColor)); + view.setOnTouchListener(onTouchListener); mViews.add(view); rootView.addView(view); } - - getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - getViewTreeObserver().removeOnGlobalLayoutListener(this); - List 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) { @@ -114,13 +101,12 @@ private boolean handleRowTouch(View view, MotionEvent event) { mActivePointerId = event.getPointerId(0); mLastDownXlat = view.getTranslationX(); - mLastDraggingView = view; mLastDownX = event.getRawX(); mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(event); - int idx = mViews.indexOf(mLastDraggingView); + int idx = mViews.indexOf(view); mSpringChain .setControlSpringIndex(idx) .getControlSpring() @@ -155,4 +141,11 @@ private boolean handleRowTouch(View view, MotionEvent event) { } return true; } + + private View.OnTouchListener onTouchListener = new OnTouchListener() { + @Override public boolean onTouch(View v, MotionEvent event) { + return handleRowTouch(v, event); + } + }; + } From 60c5178adffb15ac5353fe2661ad2cf2d5fd987b Mon Sep 17 00:00:00 2001 From: Pedro Paulo de Amorim Date: Sun, 28 Jun 2015 02:21:06 -0300 Subject: [PATCH 2/6] uncommited change --- .../playground/examples/SpringScrollViewExample.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java index 71f51ac..fe007d0 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java @@ -24,25 +24,24 @@ public class SpringScrollViewExample extends FrameLayout { - private final int ROW_COUNT = 50; + private static final String TEXT = "Row "; + private static final int ROW_COUNT = 50; public SpringScrollViewExample(Context context) { super(context); - LayoutInflater inflater = LayoutInflater.from(context); ViewGroup root = (ViewGroup) inflater.inflate(R.layout.spring_scroll_view_example, this, false); ViewGroup content = (ViewGroup) root.findViewById(R.id.content_view); addView(root); setBackgroundColor(Color.argb(255, 50, 50, 50)); - int startColor = Color.argb(255, 255, 64, 230); int endColor = Color.argb(255, 0, 174, 255); ArgbEvaluator evaluator = new ArgbEvaluator(); for (int i = 0; i < ROW_COUNT; i++) { ExampleRowView exampleRowView = new ExampleRowView(context); - Integer color = (Integer) evaluator.evaluate((float) i / (float) ROW_COUNT, startColor, endColor); - exampleRowView.setText("Row " + i); - exampleRowView.setBackgroundColor(color); + exampleRowView.setText(TEXT + i); + exampleRowView.setBackgroundColor((Integer) evaluator.evaluate( + (float) i / (float) ROW_COUNT, startColor, endColor)); content.addView(exampleRowView); } } From 18dce14acd22afafd43cb85a4ecc361d84ceab2e Mon Sep 17 00:00:00 2001 From: Pedro Paulo de Amorim Date: Sun, 28 Jun 2015 02:36:28 -0300 Subject: [PATCH 3/6] Rectoring at OverScrollView I have changed a lot of things there, the most one is about compatibility with API 14 --- rebound-android-playground/build.gradle | 2 +- .../examples/SpringScrollViewExample.java | 3 +- .../examples/scrollview/ExampleRowView.java | 6 +- .../scrollview/SpringOverScroller.java | 29 ++-- .../examples/scrollview/SpringScrollView.java | 136 +++++++----------- 5 files changed, 66 insertions(+), 110 deletions(-) diff --git a/rebound-android-playground/build.gradle b/rebound-android-playground/build.gradle index 11a3d2a..7fe2560 100644 --- a/rebound-android-playground/build.gradle +++ b/rebound-android-playground/build.gradle @@ -1,8 +1,8 @@ apply plugin: 'com.android.application' dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':rebound-android') + compile 'com.android.support:appcompat-v7:22.2.0' } android { diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java index fe007d0..43d7a55 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/SpringScrollViewExample.java @@ -37,8 +37,9 @@ public SpringScrollViewExample(Context context) { int startColor = Color.argb(255, 255, 64, 230); int endColor = Color.argb(255, 0, 174, 255); ArgbEvaluator evaluator = new ArgbEvaluator(); + LayoutInflater layoutInflater = LayoutInflater.from(getContext()); for (int i = 0; i < ROW_COUNT; i++) { - ExampleRowView exampleRowView = new ExampleRowView(context); + ExampleRowView exampleRowView = new ExampleRowView(context, layoutInflater); exampleRowView.setText(TEXT + i); exampleRowView.setBackgroundColor((Integer) evaluator.evaluate( (float) i / (float) ROW_COUNT, startColor, endColor)); diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/ExampleRowView.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/ExampleRowView.java index 42d77d5..1b9311f 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/ExampleRowView.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/ExampleRowView.java @@ -21,12 +21,12 @@ import com.facebook.rebound.playground.R; public class ExampleRowView extends FrameLayout { + private final TextView mTextView; - public ExampleRowView(Context context) { + public ExampleRowView(Context context, LayoutInflater layoutInflater) { super(context); - LayoutInflater inflater = LayoutInflater.from(context); - ViewGroup view = (ViewGroup) inflater.inflate(R.layout.example_row_view, this, false); + ViewGroup view = (ViewGroup) layoutInflater.inflate(R.layout.example_row_view, this, false); mTextView = (TextView) view.findViewById(R.id.text_view); addView(view); } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringOverScroller.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringOverScroller.java index f12b3d3..9b93d51 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringOverScroller.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringOverScroller.java @@ -42,12 +42,12 @@ public SpringOverScroller(Context context, Interpolator interpolator) { } public SpringOverScroller(Context context, Interpolator interpolator, - float bounceCoefficientX, float bounceCoefficientY) { + float bounceCoefficientX, float bounceCoefficientY) { this(context, interpolator, true); } public SpringOverScroller(Context context, Interpolator interpolator, - float bounceCoefficientX, float bounceCoefficientY, boolean flywheel) { + float bounceCoefficientX, float bounceCoefficientY, boolean flywheel) { this(context, interpolator, flywheel); } @@ -67,8 +67,7 @@ public SpringOverScroller(Context context, Interpolator interpolator, boolean fl .addSpringConfig(COASTING_CONFIG, "coasting"); } - public final void setFriction(float friction) { - } + public final void setFriction(float friction) { } public final boolean isFinished() { return mSpringX.isAtRest() && mSpringY.isAtRest(); @@ -149,34 +148,24 @@ public void fling(int startX, int startY, int velocityX, int velocityY, .setVelocity(velocityY); } - public void notifyHorizontalEdgeReached(int startX, int finalX, int overX) { - } + public void notifyHorizontalEdgeReached(int startX, int finalX, int overX) { } - public void notifyVerticalEdgeReached(int startY, int finalY, int overY) { - } + public void notifyVerticalEdgeReached(int startY, int finalY, int overY) { } public void abortAnimation() { mSpringX.setAtRest(); mSpringY.setAtRest(); } - @Override - public void onSpringUpdate(Spring spring) { + @Override public void onSpringUpdate(Spring spring) { Log.d("WSB", "cv:" + spring.getCurrentValue()); } @Override - public void onSpringAtRest(Spring spring) { + public void onSpringAtRest(Spring spring) { } - } + @Override public void onSpringActivate(Spring spring) { } - @Override - public void onSpringActivate(Spring spring) { + @Override public void onSpringEndStateChange(Spring spring) { } - } - - @Override - public void onSpringEndStateChange(Spring spring) { - - } } diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringScrollView.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringScrollView.java index e2a6f0f..fafa6fe 100644 --- a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringScrollView.java +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/examples/scrollview/SpringScrollView.java @@ -19,6 +19,9 @@ import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityEventCompat; +import android.support.v4.view.accessibility.AccessibilityRecordCompat; import android.util.AttributeSet; import android.util.Log; import android.view.FocusFinder; @@ -38,10 +41,9 @@ import java.util.List; public class SpringScrollView extends FrameLayout { - static final int ANIMATED_SCROLL_GAP = 250; - - static final float MAX_SCROLL_FACTOR = 0.5f; + public static final int ANIMATED_SCROLL_GAP = 250; + public static final float MAX_SCROLL_FACTOR = 0.5f; private static final String TAG = "ScrollView"; private long mLastScroll; @@ -131,23 +133,19 @@ public SpringScrollView(Context context, AttributeSet attrs, int defStyle) { // a.recycle(); } - @Override - public int getOverScrollMode() { + @Override public int getOverScrollMode() { return OVER_SCROLL_ALWAYS; } - @Override - public boolean shouldDelayChildPressedState() { + @Override public boolean shouldDelayChildPressedState() { return true; } - @Override - protected float getTopFadingEdgeStrength() { + @Override protected float getTopFadingEdgeStrength() { return 0; } - @Override - protected float getBottomFadingEdgeStrength() { + @Override protected float getBottomFadingEdgeStrength() { return 0; } @@ -173,8 +171,7 @@ private void initScrollView() { mOverflingDistance = configuration.getScaledOverflingDistance(); } - @Override - public void addView(View child) { + @Override public void addView(View child) { if (getChildCount() > 0) { throw new IllegalStateException("ScrollView can host only one direct child"); } @@ -182,8 +179,7 @@ public void addView(View child) { super.addView(child); } - @Override - public void addView(View child, int index) { + @Override public void addView(View child, int index) { if (getChildCount() > 0) { throw new IllegalStateException("ScrollView can host only one direct child"); } @@ -191,8 +187,7 @@ public void addView(View child, int index) { super.addView(child, index); } - @Override - public void addView(View child, ViewGroup.LayoutParams params) { + @Override public void addView(View child, ViewGroup.LayoutParams params) { if (getChildCount() > 0) { throw new IllegalStateException("ScrollView can host only one direct child"); } @@ -200,8 +195,7 @@ public void addView(View child, ViewGroup.LayoutParams params) { super.addView(child, params); } - @Override - public void addView(View child, int index, ViewGroup.LayoutParams params) { + @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { if (getChildCount() > 0) { throw new IllegalStateException("ScrollView can host only one direct child"); } @@ -263,8 +257,7 @@ public void setSmoothScrollingEnabled(boolean smoothScrollingEnabled) { mSmoothScrollingEnabled = smoothScrollingEnabled; } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (!mFillViewport) { @@ -294,8 +287,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { } } - @Override - public boolean dispatchKeyEvent(KeyEvent event) { + @Override public boolean dispatchKeyEvent(KeyEvent event) { // Let the focused view and/or our descendants get the key first return super.dispatchKeyEvent(event) || executeKeyEvent(event); } @@ -383,8 +375,7 @@ private void recycleVelocityTracker() { } } - @Override - public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { + @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { if (disallowIntercept) { recycleVelocityTracker(); } @@ -392,8 +383,7 @@ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { } - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { /* * This method JUST determines whether we want to intercept the motion. * If we return true, onMotionEvent will be called and we do the actual @@ -489,7 +479,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { mActivePointerId = INVALID_POINTER; recycleVelocityTracker(); if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) { - postInvalidateOnAnimation(); + ViewCompat.postInvalidateOnAnimation(this); } break; case MotionEvent.ACTION_POINTER_UP: @@ -504,8 +494,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { return mIsBeingDragged; } - @Override - public boolean onTouchEvent(MotionEvent ev) { + @Override public boolean onTouchEvent(MotionEvent ev) { initVelocityTrackerIfNotExists(); mVelocityTracker.addMovement(ev); @@ -589,7 +578,7 @@ public boolean onTouchEvent(MotionEvent ev) { } else { if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) { - postInvalidateOnAnimation(); + ViewCompat.postInvalidateOnAnimation(this); } } } @@ -601,7 +590,7 @@ public boolean onTouchEvent(MotionEvent ev) { case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged && getChildCount() > 0) { if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) { - postInvalidateOnAnimation(); + ViewCompat.postInvalidateOnAnimation(this); } mActivePointerId = INVALID_POINTER; endDrag(); @@ -667,8 +656,7 @@ private void onSecondaryPointerUp(MotionEvent ev) { // return super.onGenericMotionEvent(event); // } - @Override - protected void onOverScrolled(int scrollX, int scrollY, + @Override protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { // Treat animating scrolls differently; see #computeScroll() for why. if (!mScroller.isFinished()) { @@ -695,8 +683,7 @@ private void invalidateParentIfNeeded() { } } - @Override - public boolean performAccessibilityAction(int action, Bundle arguments) { + @Override public boolean performAccessibilityAction(int action, Bundle arguments) { if (super.performAccessibilityAction(action, arguments)) { return true; } @@ -724,8 +711,7 @@ public boolean performAccessibilityAction(int action, Bundle arguments) { return false; } - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(SpringScrollView.class.getName()); if (isEnabled()) { @@ -742,16 +728,16 @@ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { } } - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(SpringScrollView.class.getName()); final boolean scrollable = getScrollRange() > 0; event.setScrollable(scrollable); event.setScrollX(getScrollX()); event.setScrollY(getScrollY()); - event.setMaxScrollX(getScrollX()); - event.setMaxScrollY(getScrollRange()); + AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event); + record.setMaxScrollX(getScrollX()); + record.setMaxScrollY(getScrollRange()); } private int getScrollRange() { @@ -1064,7 +1050,7 @@ public final void smoothScrollBy(int dx, int dy) { dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY; mScroller.startScroll(getScrollX(), scrollY, 0, dy); - postInvalidateOnAnimation(); + ViewCompat.postInvalidateOnAnimation(this); } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); @@ -1088,8 +1074,7 @@ public final void smoothScrollTo(int x, int y) { *

The scroll range of a scroll view is the overall height of all of its * children.

*/ - @Override - protected int computeVerticalScrollRange() { + @Override protected int computeVerticalScrollRange() { final int count = getChildCount(); final int contentHeight = getHeight() - getPaddingBottom() - getPaddingTop(); if (count == 0) { @@ -1108,13 +1093,11 @@ protected int computeVerticalScrollRange() { return scrollRange; } - @Override - protected int computeVerticalScrollOffset() { + @Override protected int computeVerticalScrollOffset() { return Math.max(0, super.computeVerticalScrollOffset()); } - @Override - protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) { + @Override protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) { ViewGroup.LayoutParams lp = child.getLayoutParams(); int childWidthMeasureSpec; @@ -1128,8 +1111,7 @@ protected void measureChild(View child, int parentWidthMeasureSpec, int parentHe child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } - @Override - protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, + @Override protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); @@ -1142,8 +1124,7 @@ protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, i child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } - @Override - public void computeScroll() { + @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { // This is called at drawing time by ViewGroup. We don't want to // re-show the scrollbars at this point, which scrollTo will do, @@ -1179,7 +1160,7 @@ public void computeScroll() { if (!awakenScrollBars()) { // Keep on drawing until the animation has finished. - postInvalidateOnAnimation(); + ViewCompat.postInvalidateOnAnimation(this); } } } @@ -1289,8 +1270,7 @@ protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) { return scrollYDelta; } - @Override - public void requestChildFocus(View child, View focused) { + @Override public void requestChildFocus(View child, View focused) { if (!mIsLayoutDirty) { scrollToChild(focused); } else { @@ -1308,8 +1288,7 @@ public void requestChildFocus(View child, View focused) { * This is more expensive than the default {@link android.view.ViewGroup} * implementation, otherwise this behavior might have been made the default. */ - @Override - protected boolean onRequestFocusInDescendants(int direction, + @Override protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { // convert from forward / backward notation to up / down / left / right @@ -1336,8 +1315,7 @@ protected boolean onRequestFocusInDescendants(int direction, return nextFocus.requestFocus(direction, previouslyFocusedRect); } - @Override - public boolean requestChildRectangleOnScreen(View child, Rect rectangle, + @Override public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) { // offset into coordinate space of this scroll view rectangle.offset(child.getLeft() - child.getScrollX(), @@ -1346,19 +1324,16 @@ public boolean requestChildRectangleOnScreen(View child, Rect rectangle, return scrollToChildRect(rectangle, immediate); } - @Override - public void requestLayout() { + @Override public void requestLayout() { mIsLayoutDirty = true; super.requestLayout(); } - @Override - protected void onDetachedFromWindow() { + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { + @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mIsLayoutDirty = false; // Give a child focus if it needs it @@ -1367,7 +1342,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { } mChildToScrollTo = null; - if (!isLaidOut()) { + if (!ViewCompat.isLaidOut(this)) { if (mSavedState != null) { setScrollY(mSavedState.scrollPosition); mSavedState = null; @@ -1389,8 +1364,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { scrollTo(getScrollX(), getScrollY()); } - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); View currentFocused = findFocus(); @@ -1435,7 +1409,7 @@ public void fling(int velocityY) { mScroller.fling(getScrollX(), getScrollY(), 0, velocityY, 0, 0, 0, Math.max(0, bottom - height), 0, height/2); - postInvalidateOnAnimation(); + ViewCompat.postInvalidateOnAnimation(this); } } @@ -1449,8 +1423,7 @@ private void endDrag() { * *

This version also clamps the scrolling to the bounds of our child. */ - @Override - public void scrollTo(int x, int y) { + @Override public void scrollTo(int x, int y) { // we rely on the fact the View.scrollBy calls scrollTo. if (getChildCount() > 0) { if (x != getScrollX() || y != getScrollY()) { @@ -1459,17 +1432,13 @@ public void scrollTo(int x, int y) { } } - @Override - public void setOverScrollMode(int mode) { - } + @Override public void setOverScrollMode(int mode) { } - @Override - public void draw(Canvas canvas) { + @Override public void draw(Canvas canvas) { super.draw(canvas); } - @Override - protected void onRestoreInstanceState(Parcelable state) { + @Override protected void onRestoreInstanceState(Parcelable state) { if (getContext().getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) { // Some old apps reused IDs in ways they shouldn't have. // Don't break them, but they don't get scroll state restoration. @@ -1482,8 +1451,7 @@ protected void onRestoreInstanceState(Parcelable state) { requestLayout(); } - @Override - protected Parcelable onSaveInstanceState() { + @Override protected Parcelable onSaveInstanceState() { if (getContext().getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) { // Some old apps reused IDs in ways they shouldn't have. // Don't break them, but they don't get scroll state restoration. @@ -1507,14 +1475,12 @@ public SavedState(Parcel source) { scrollPosition = source.readInt(); } - @Override - public void writeToParcel(Parcel dest, int flags) { + @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(scrollPosition); } - @Override - public String toString() { + @Override public String toString() { return "HorizontalScrollView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " scrollPosition=" + scrollPosition + "}"; From 419f51e30df09fcd7361ce6dcae71990b25a8fa2 Mon Sep 17 00:00:00 2001 From: Pedro Paulo de Amorim Date: Sun, 28 Jun 2015 03:32:17 -0300 Subject: [PATCH 4/6] Structure changes --- .../main/res/layout/activity_playground.xml | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/rebound-android-playground/src/main/res/layout/activity_playground.xml b/rebound-android-playground/src/main/res/layout/activity_playground.xml index a2ba514..e68f92f 100644 --- a/rebound-android-playground/src/main/res/layout/activity_playground.xml +++ b/rebound-android-playground/src/main/res/layout/activity_playground.xml @@ -1,37 +1,30 @@ + android:background="@android:color/black"> + - + + - - + android:layout_gravity="center" + android:padding="40dp"/> + + android:background="#ccc"/> + + From e7df1fe71dd268ebd8c5d88323eafda9696dbe08 Mon Sep 17 00:00:00 2001 From: Pedro Paulo de Amorim Date: Sun, 28 Jun 2015 04:10:28 -0300 Subject: [PATCH 5/6] Example and Playground updated Changes on Example structure and some corrections at PlaygroundActivity --- build.gradle | 6 + rebound-android-example/build.gradle | 2 + .../src/main/AndroidManifest.xml | 5 +- .../rebound/example/MainActivity.java | 112 +++++++++------- .../src/main/res/layout/main.xml | 18 +-- .../src/main/res/values/colors.xml | 4 + .../src/main/res/values/styles.xml | 12 ++ rebound-android-playground/build.gradle | 1 + .../src/main/AndroidManifest.xml | 4 +- .../playground/app/AbstractActivity.java | 17 +++ .../playground/app/PlaygroundActivity.java | 121 ++++++++---------- .../src/main/res/values/colors.xml | 2 + .../src/main/res/values/styles.xml | 8 +- 13 files changed, 185 insertions(+), 127 deletions(-) create mode 100644 rebound-android-example/src/main/res/values/colors.xml create mode 100644 rebound-android-example/src/main/res/values/styles.xml create mode 100644 rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/AbstractActivity.java diff --git a/build.gradle b/build.gradle index 23c9b17..a540605 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,12 @@ buildscript { } } +allprojects { + repositories { + mavenCentral() + } +} + apply plugin: 'com.android.library' import com.android.builder.core.BuilderConstants diff --git a/rebound-android-example/build.gradle b/rebound-android-example/build.gradle index d36eeea..374bd2a 100644 --- a/rebound-android-example/build.gradle +++ b/rebound-android-example/build.gradle @@ -2,6 +2,8 @@ apply plugin: 'com.android.application' dependencies { compile project(':rebound-android') + compile 'com.android.support:appcompat-v7:22.2.0' + compile 'com.jakewharton:butterknife:7.0.0' } android { diff --git a/rebound-android-example/src/main/AndroidManifest.xml b/rebound-android-example/src/main/AndroidManifest.xml index 0cdd25f..4c15319 100644 --- a/rebound-android-example/src/main/AndroidManifest.xml +++ b/rebound-android-example/src/main/AndroidManifest.xml @@ -10,11 +10,10 @@ android:label="Rebound Example" android:hardwareAccelerated="true" android:allowBackup="false" - android:icon="@drawable/rebound_icon" - > + android:icon="@drawable/rebound_icon"> diff --git a/rebound-android-example/src/main/java/com/facebook/rebound/example/MainActivity.java b/rebound-android-example/src/main/java/com/facebook/rebound/example/MainActivity.java index 9ab49ff..da0c722 100644 --- a/rebound-android-example/src/main/java/com/facebook/rebound/example/MainActivity.java +++ b/rebound-android-example/src/main/java/com/facebook/rebound/example/MainActivity.java @@ -14,10 +14,13 @@ import android.app.Activity; import android.os.Bundle; +import android.support.v4.view.ViewCompat; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; +import butterknife.Bind; +import butterknife.ButterKnife; import com.facebook.rebound.BaseSpringSystem; import com.facebook.rebound.SimpleSpringListener; import com.facebook.rebound.Spring; @@ -36,68 +39,87 @@ public class MainActivity extends Activity { private final BaseSpringSystem mSpringSystem = SpringSystem.create(); private final ExampleSpringListener mSpringListener = new ExampleSpringListener(); - private FrameLayout mRootView; + private Spring mScaleSpring; - private View mImageView; + + @Bind(R.id.root_view) FrameLayout mRootView; + @Bind(R.id.image_view) View mImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.main); - mRootView = (FrameLayout) findViewById(R.id.root_view); - mImageView = mRootView.findViewById(R.id.image_view); - - // Create the animation spring. - mScaleSpring = mSpringSystem.createSpring(); - - // Add an OnTouchListener to the root view. - mRootView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // When pressed start solving the spring to 1. - mScaleSpring.setEndValue(1); - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - // When released start solving the spring to 0. - mScaleSpring.setEndValue(0); - break; - } - return true; - } - }); + ButterKnife.bind(this); + mRootView.setOnTouchListener(onTouchListener); } - @Override - public void onResume() { + /** + * Add a listener to the spring when the Activity resumes. + */ + @Override public void onResume() { super.onResume(); - // Add a listener to the spring when the Activity resumes. - mScaleSpring.addListener(mSpringListener); + scaleSpring().addListener(mSpringListener); } - @Override - public void onPause() { + /** + * Remove the listener to the spring when the Activity pauses. + */ + @Override public void onPause() { + scaleSpring().removeListener(mSpringListener); super.onPause(); - // Remove the listener to the spring when the Activity pauses. - mScaleSpring.removeListener(mSpringListener); } + /** + * Create a new instance if spring if needed + * + * @return instance of Spring + */ + private Spring scaleSpring() { + if(mScaleSpring == null) { + mScaleSpring = mSpringSystem.createSpring(); + } + return mScaleSpring; + } + + /** + * On each update of the spring value, we adjust the scale of the image view to match the + * springs new value. We use the SpringUtil linear interpolation function mapValueFromRangeToRange + * to translate the spring's 0 to 1 scale to a 100% to 50% scale range and apply that to the View + * with setScaleX/Y. Note that rendering is an implementation detail of the application and not + * Rebound itself. If you need Gingerbread compatibility consider using ViewCompat to update + * your view properties in a backwards compatible manner. + */ private class ExampleSpringListener extends SimpleSpringListener { - @Override - public void onSpringUpdate(Spring spring) { - // On each update of the spring value, we adjust the scale of the image view to match the - // springs new value. We use the SpringUtil linear interpolation function mapValueFromRangeToRange - // to translate the spring's 0 to 1 scale to a 100% to 50% scale range and apply that to the View - // with setScaleX/Y. Note that rendering is an implementation detail of the application and not - // Rebound itself. If you need Gingerbread compatibility consider using NineOldAndroids to update - // your view properties in a backwards compatible manner. + @Override public void onSpringUpdate(Spring spring) { float mappedValue = (float) SpringUtil.mapValueFromRangeToRange(spring.getCurrentValue(), 0, 1, 1, 0.5); - mImageView.setScaleX(mappedValue); - mImageView.setScaleY(mappedValue); + ViewCompat.setScaleX(mImageView, mappedValue); + ViewCompat.setScaleY(mImageView, mappedValue); } } + /** + * # MotionEvent.ACTION_DOWN: + * When pressed start solving the spring to 1. + * + * #MotionEvent.ACTION_UP: + * #MotionEvent.ACTION_CANCEL: + * When released start solving the spring to 0. + */ + private View.OnTouchListener onTouchListener = new View.OnTouchListener() { + @Override public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + scaleSpring().setEndValue(1); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + scaleSpring().setEndValue(0); + break; + default: + break; + } + return true; + } + }; + } diff --git a/rebound-android-example/src/main/res/layout/main.xml b/rebound-android-example/src/main/res/layout/main.xml index 46b4612..9e0a9b7 100644 --- a/rebound-android-example/src/main/res/layout/main.xml +++ b/rebound-android-example/src/main/res/layout/main.xml @@ -1,21 +1,21 @@ + android:id="@+id/root_view" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + android:scaleType="centerCrop"/> + + android:layout_gravity="bottom"/> + diff --git a/rebound-android-example/src/main/res/values/colors.xml b/rebound-android-example/src/main/res/values/colors.xml new file mode 100644 index 0000000..4ef080b --- /dev/null +++ b/rebound-android-example/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #000000 + \ No newline at end of file diff --git a/rebound-android-example/src/main/res/values/styles.xml b/rebound-android-example/src/main/res/values/styles.xml new file mode 100644 index 0000000..d65ab9c --- /dev/null +++ b/rebound-android-example/src/main/res/values/styles.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/rebound-android-playground/build.gradle b/rebound-android-playground/build.gradle index 7fe2560..9bc4344 100644 --- a/rebound-android-playground/build.gradle +++ b/rebound-android-playground/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'com.android.application' dependencies { compile project(':rebound-android') compile 'com.android.support:appcompat-v7:22.2.0' + compile 'com.jakewharton:butterknife:7.0.0' } android { diff --git a/rebound-android-playground/src/main/AndroidManifest.xml b/rebound-android-playground/src/main/AndroidManifest.xml index dd01c56..4122165 100644 --- a/rebound-android-playground/src/main/AndroidManifest.xml +++ b/rebound-android-playground/src/main/AndroidManifest.xml @@ -8,11 +8,9 @@ android:icon="@drawable/rebound_icon" android:label="@string/app_name" android:theme="@style/AppTheme" - android:hardwareAccelerated="true" - > + android:hardwareAccelerated="true"> diff --git a/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/AbstractActivity.java b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/AbstractActivity.java new file mode 100644 index 0000000..a83ca11 --- /dev/null +++ b/rebound-android-playground/src/main/java/com/facebook/rebound/playground/app/AbstractActivity.java @@ -0,0 +1,17 @@ +package com.facebook.rebound.playground.app; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import butterknife.ButterKnife; + +public abstract class AbstractActivity extends AppCompatActivity { + + @Override protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(getContentViewId()); + ButterKnife.bind(this); + } + + protected abstract int getContentViewId(); + +} 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 c24b138..a9c8e47 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 @@ -15,6 +15,7 @@ import android.app.Activity; import android.content.Context; import android.database.DataSetObserver; +import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; @@ -25,6 +26,7 @@ import android.widget.ListAdapter; import android.widget.ListView; +import butterknife.Bind; import com.facebook.rebound.SpringUtil; import com.facebook.rebound.playground.R; import com.facebook.rebound.playground.examples.BallExample; @@ -39,9 +41,9 @@ import java.util.ArrayList; import java.util.List; -public class PlaygroundActivity extends Activity implements AdapterView.OnItemClickListener { +public class PlaygroundActivity extends AbstractActivity implements AdapterView.OnItemClickListener { - private static final List SAMPLES = new ArrayList(); + private static final List SAMPLES = new ArrayList<>(); static { SAMPLES.add(new Sample(SimpleExample.class, "Simple Example", "Scale a photo when you press and release")); @@ -52,49 +54,54 @@ public class PlaygroundActivity extends Activity implements AdapterView.OnItemCl SAMPLES.add(new Sample(OrigamiExample.class, "Origami Example", "Rebound port of an Origami composition")); } - private ListView mListView; - private View mRootContainer; - private ExampleListAdapter mAdapter; - private ViewGroup mRootView; private ExampleContainerView mCurrentExample; private boolean mAnimating; - private LayoutInflater mInflater; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_playground); - mInflater = LayoutInflater.from(this); - mRootView = (ViewGroup) findViewById(R.id.root); - mRootContainer = findViewById(R.id.root_container); - mListView = (ListView) findViewById(R.id.list_view); - mAdapter = new ExampleListAdapter(); - mListView.setAdapter(mAdapter); + @Bind(R.id.root_container) View mRootContainer; + @Bind(R.id.root) ViewGroup mRootView; + @Bind(R.id.list_view) ListView mListView; + + @Override protected int getContentViewId() { + return R.layout.activity_playground; + } + @Override protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mListView.setAdapter(new ExampleListAdapter()); mListView.setOnItemClickListener(this); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { + @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.playground, menu); return true; } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - if (id == R.id.action_settings) { - return true; - } - return super.onOptionsItemSelected(item); + @Override public boolean onOptionsItemSelected(MenuItem item) { + return item.getItemId() == R.id.action_settings || super.onOptionsItemSelected(item); } - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { + @Override public void onItemClick(AdapterView parent, View view, int position, long id) { if (mAnimating) { return; } + if(position == 0) { + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + getWindow().getDecorView() + .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_FULLSCREEN); + } else if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + getWindow().getDecorView() + .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_LOW_PROFILE); + } + } + Class clazz = SAMPLES.get(position).viewClass; View sampleView = null; try { @@ -120,19 +127,16 @@ public void onItemClick(AdapterView parent, View view, int position, long id) mRootView.addView(mCurrentExample); mCurrentExample.postDelayed(new Runnable() { - @Override - public void run() { + @Override public void run() { mCurrentExample.reveal(true, new ExampleContainerView.Callback() { - @Override - public void onProgress(double progress) { + @Override public void onProgress(double progress) { float scale = (float) SpringUtil.mapValueFromRangeToRange(progress, 0, 1, 0.8, 1); mRootContainer.setScaleX(scale); mRootContainer.setScaleY(scale); mRootContainer.setAlpha((float) progress); } - @Override - public void onEnd() { + @Override public void onEnd() { mAnimating = false; } }); @@ -140,62 +144,54 @@ public void onEnd() { }, 100); } - @Override - public void onBackPressed() { + @Override public void onBackPressed() { if (mAnimating || mCurrentExample == null) { + super.onBackPressed(); return; } mAnimating = true; mCurrentExample.hide(true, new ExampleContainerView.Callback() { - @Override - public void onProgress(double progress) { + @Override public void onProgress(double progress) { float scale = (float) SpringUtil.mapValueFromRangeToRange(progress, 0, 1, 0.8, 1); mRootContainer.setScaleX(scale); mRootContainer.setScaleY(scale); mRootContainer.setAlpha((float) progress); } - @Override - public void onEnd() { + @Override public void onEnd() { mAnimating = false; mCurrentExample.clearCallback(); mRootView.removeView(mCurrentExample); mCurrentExample = null; + getWindow().getDecorView() + .setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } }); } private class ExampleListAdapter implements ListAdapter { - @Override - public void registerDataSetObserver(DataSetObserver observer) {} + @Override public void registerDataSetObserver(DataSetObserver observer) { } - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - } + @Override public void unregisterDataSetObserver(DataSetObserver observer) { } - @Override - public int getCount() { + @Override public int getCount() { return SAMPLES.size(); } - @Override - public Object getItem(int position) { + @Override public Object getItem(int position) { return SAMPLES.get(position); } - @Override - public long getItemId(int position) { + @Override public long getItemId(int position) { return position; } - @Override - public boolean hasStableIds() { + @Override public boolean hasStableIds() { return true; } - @Override - public View getView(int position, View convertView, ViewGroup parent) { + @Override public View getView(int position, View convertView, ViewGroup parent) { RowView rowView; if (convertView != null) { rowView = (RowView) convertView; @@ -207,28 +203,23 @@ public View getView(int position, View convertView, ViewGroup parent) { return rowView; } - @Override - public int getItemViewType(int position) { + @Override public int getItemViewType(int position) { return 0; } - @Override - public int getViewTypeCount() { + @Override public int getViewTypeCount() { return 1; } - @Override - public boolean isEmpty() { + @Override public boolean isEmpty() { return SAMPLES.isEmpty(); } - @Override - public boolean areAllItemsEnabled() { + @Override public boolean areAllItemsEnabled() { return true; } - @Override - public boolean isEnabled(int position) { + @Override public boolean isEnabled(int position) { return true; } } diff --git a/rebound-android-playground/src/main/res/values/colors.xml b/rebound-android-playground/src/main/res/values/colors.xml index a8d4bbf..3b680e7 100644 --- a/rebound-android-playground/src/main/res/values/colors.xml +++ b/rebound-android-playground/src/main/res/values/colors.xml @@ -1,4 +1,6 @@ #efefef + #1194e7 + #1085CE \ No newline at end of file diff --git a/rebound-android-playground/src/main/res/values/styles.xml b/rebound-android-playground/src/main/res/values/styles.xml index e88687c..231d124 100644 --- a/rebound-android-playground/src/main/res/values/styles.xml +++ b/rebound-android-playground/src/main/res/values/styles.xml @@ -1,8 +1,12 @@ - From 1a7ff00f48ac46bbd367f1b19799678c07770473 Mon Sep 17 00:00:00 2001 From: Pedro Paulo de Amorim Date: Mon, 29 Jun 2015 23:12:08 -0300 Subject: [PATCH 6/6] Api downgrade and minor changes --- rebound-android-example/src/main/AndroidManifest.xml | 9 +++++---- rebound-android-playground/build.gradle | 2 +- rebound-android-playground/src/main/AndroidManifest.xml | 5 +++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/rebound-android-example/src/main/AndroidManifest.xml b/rebound-android-example/src/main/AndroidManifest.xml index 4c15319..7588d2d 100644 --- a/rebound-android-example/src/main/AndroidManifest.xml +++ b/rebound-android-example/src/main/AndroidManifest.xml @@ -1,16 +1,15 @@ - - + + + + diff --git a/rebound-android-playground/build.gradle b/rebound-android-playground/build.gradle index 9bc4344..ca3fd86 100644 --- a/rebound-android-playground/build.gradle +++ b/rebound-android-playground/build.gradle @@ -15,7 +15,7 @@ android { applicationId "com.facebook.rebound.androidplayground" versionCode Integer.parseInt(project.VERSION_CODE) versionName project.VERSION_NAME - minSdkVersion 14 + minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK) targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION) } diff --git a/rebound-android-playground/src/main/AndroidManifest.xml b/rebound-android-playground/src/main/AndroidManifest.xml index 4122165..b5c7729 100644 --- a/rebound-android-playground/src/main/AndroidManifest.xml +++ b/rebound-android-playground/src/main/AndroidManifest.xml @@ -1,14 +1,14 @@ - + + +