Skip to content

Commit

Permalink
Fix Dribbble shot return when parallax is applied.
Browse files Browse the repository at this point in the history
  • Loading branch information
nickbutcher committed Aug 3, 2016
1 parent 64d6cfb commit f98b876
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 50 deletions.
26 changes: 6 additions & 20 deletions app/src/main/java/io/plaidapp/ui/DribbbleShot.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,14 @@ protected void onCreate(final Bundle savedInstanceState) {
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
expandImageAndFinish();
setResultAndFinish();
}
});
fab.setOnClickListener(fabClick);
chromeFader = new ElasticDragDismissFrameLayout.SystemChromeFader(this) {
@Override
public void onDragDismissed() {
expandImageAndFinish();
setResultAndFinish();
}
};

Expand Down Expand Up @@ -254,12 +254,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {

@Override
public void onBackPressed() {
expandImageAndFinish();
setResultAndFinish();
}

@Override
public boolean onNavigateUp() {
expandImageAndFinish();
setResultAndFinish();
return true;
}

Expand Down Expand Up @@ -639,25 +639,11 @@ public void onResponse(Call<List<Comment>> call, Response<List<Comment>> respons
});
}

private void expandImageAndFinish() {
private void setResultAndFinish() {
final Intent resultData = new Intent();
resultData.putExtra(RESULT_EXTRA_SHOT_ID, shot.id);
setResult(RESULT_OK, resultData);
if (imageView.getOffset() != 0f) {
Animator expandImage = ObjectAnimator.ofFloat(imageView, ParallaxScrimageView.OFFSET,
0f);
expandImage.setDuration(80);
expandImage.setInterpolator(getFastOutSlowInInterpolator(this));
expandImage.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
finishAfterTransition();
}
});
expandImage.start();
} else {
finishAfterTransition();
}
finishAfterTransition();
}

private void calculateFabPosition() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.plaidapp.ui.transitions;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.transition.ChangeBounds;
import android.transition.TransitionValues;
import android.util.AttributeSet;
import android.view.ViewGroup;

import io.plaidapp.ui.widget.ParallaxScrimageView;

/**
* An extension to {@link ChangeBounds} designed to work with {@link ParallaxScrimageView}. This
* will remove any parallax applied while also performing a {@code ChangeBounds} transition.
*/
public class DeparallaxingChangeBounds extends ChangeBounds {

private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";

public DeparallaxingChangeBounds(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public void captureEndValues(TransitionValues transitionValues) {
super.captureEndValues(transitionValues);
if (!(transitionValues.view instanceof ParallaxScrimageView)) return;
ParallaxScrimageView psv = ((ParallaxScrimageView) transitionValues.view);
if (psv.getOffset() == 0) return;

// as we're going to remove the offset (which drives the parallax) we need to
// compensate for this by adjusting the target bounds.
Rect bounds = (Rect) transitionValues.values.get(PROPNAME_BOUNDS);
bounds.offset(0, -psv.getOffset());
transitionValues.values.put(PROPNAME_BOUNDS, bounds);
}

@Override
public Animator createAnimator(ViewGroup sceneRoot,
TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null
|| !(endValues.view instanceof ParallaxScrimageView)) return null;
Animator changeBounds = super.createAnimator(sceneRoot, startValues, endValues);
ParallaxScrimageView psv = ((ParallaxScrimageView) endValues.view);
if (psv.getOffset() == 0) return changeBounds;

Animator deparallax = ObjectAnimator.ofInt(psv, ParallaxScrimageView.OFFSET, 0);
AnimatorSet transition = new AnimatorSet();
transition.playTogether(changeBounds, deparallax);
return transition;
}
}
67 changes: 40 additions & 27 deletions app/src/main/java/io/plaidapp/ui/widget/ParallaxScrimageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,47 +19,52 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Property;

import io.plaidapp.R;
import io.plaidapp.util.AnimUtils;
import io.plaidapp.util.ColorUtils;
import io.plaidapp.util.ViewOffsetHelper;

/**
* An image view which supports parallax scrolling and applying a scrim onto it's content. Get it.
*
* <p>
* It also has a custom pinned state, for use via state lists.
*/
public class ParallaxScrimageView extends FourThreeImageView {

private static final int[] STATE_PINNED = {R.attr.state_pinned};
private static final int[] STATE_PINNED = { R.attr.state_pinned };
private final Paint scrimPaint;
private int imageOffset;
private int minOffset;
private ViewOffsetHelper offsetHelper;
private Rect clipBounds = new Rect();
private float scrimAlpha = 0f;
private float maxScrimAlpha = 1f;
private int scrimColor = 0x00000000;
private int scrimColor = Color.TRANSPARENT;
private float parallaxFactor = -0.5f;
private boolean isPinned = false;
private boolean immediatePin = false;
public static final Property<ParallaxScrimageView, Float> OFFSET = new AnimUtils
.FloatProperty<ParallaxScrimageView>("offset") {

@Override
public void setValue(ParallaxScrimageView parallaxScrimageView, float value) {
parallaxScrimageView.setOffset(value);
}
public static final Property<ParallaxScrimageView, Integer> OFFSET =
new AnimUtils.IntProperty<ParallaxScrimageView>("offset") {

@Override
public Float get(ParallaxScrimageView parallaxScrimageView) {
return parallaxScrimageView.getOffset();
}
};
@Override
public void setValue(ParallaxScrimageView parallaxScrimageView, int value) {
parallaxScrimageView.setOffset(value);
}

@Override
public Integer get(ParallaxScrimageView parallaxScrimageView) {
return parallaxScrimageView.getOffset();
}
};

public ParallaxScrimageView(Context context, AttributeSet attrs) {
super(context, attrs);
Expand All @@ -84,35 +89,38 @@ public ParallaxScrimageView(Context context, AttributeSet attrs) {

scrimPaint = new Paint();
scrimPaint.setColor(ColorUtils.modifyAlpha(scrimColor, scrimAlpha));
offsetHelper = new ViewOffsetHelper(this);
}

public float getOffset() {
return getTranslationY();
public int getOffset() {
return offsetHelper.getTopAndBottomOffset();
}

public void setOffset(float offset) {
public void setOffset(int offset) {
offset = Math.max(minOffset, offset);
if (offset != getTranslationY()) {
setTranslationY(offset);
if (offset != offsetHelper.getTopAndBottomOffset()) {
offsetHelper.setTopAndBottomOffset(offset);
imageOffset = (int) (offset * parallaxFactor);
setScrimAlpha(Math.min((-offset / getMinimumHeight()) * maxScrimAlpha, maxScrimAlpha));
ViewCompat.postInvalidateOnAnimation(this);
clipBounds.set(0, 0, getWidth(), getHeight() + Math.round(imageOffset));
setClipBounds(clipBounds);
setScrimAlpha(Math.min(((float) -offset / getMinimumHeight()) * maxScrimAlpha, maxScrimAlpha));
postInvalidateOnAnimation();
}
setPinned(offset == minOffset);
}

public void setScrimColor(@ColorInt int scrimColor) {
if (this.scrimColor != scrimColor) {
this.scrimColor = scrimColor;
ViewCompat.postInvalidateOnAnimation(this);
postInvalidateOnAnimation();
}
}

public void setScrimAlpha(@FloatRange(from = 0f, to = 1f) float alpha) {
if (scrimAlpha != alpha) {
scrimAlpha = alpha;
scrimPaint.setColor(ColorUtils.modifyAlpha(scrimColor, scrimAlpha));
ViewCompat.postInvalidateOnAnimation(this);
postInvalidateOnAnimation();
}
}

Expand All @@ -124,15 +132,20 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
}
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
offsetHelper.onViewLayout();
}

@Override
protected void onDraw(Canvas canvas) {
if (imageOffset != 0) {
canvas.save();
final int saveCount = canvas.save();
canvas.translate(0f, imageOffset);
canvas.clipRect(0f, 0f, canvas.getWidth(), canvas.getHeight() + imageOffset);
super.onDraw(canvas);
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), scrimPaint);
canvas.restore();
canvas.restoreToCount(saveCount);
} else {
super.onDraw(canvas);
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), scrimPaint);
Expand Down
7 changes: 4 additions & 3 deletions app/src/main/res/transition/dribbble_shot_shared_return.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>

<!--
Copyright 2015 Google Inc.
Expand Down Expand Up @@ -29,10 +28,12 @@
<changeTransform />
</transitionSet>

<changeBounds android:interpolator="@android:interpolator/fast_out_slow_in">
<transition
class="io.plaidapp.ui.transitions.DeparallaxingChangeBounds"
android:interpolator="@android:interpolator/fast_out_slow_in">
<targets>
<target android:targetId="@id/shot" />
</targets>
</changeBounds>
</transition>

</transitionSet>

0 comments on commit f98b876

Please sign in to comment.