To achieve what you want, you need to do two more things in your animators:
- rotate the view using a point that is not standard by default (placed in the middle of the view).
- translate view while spinning
In both cases, you need to know the size of your view, so I would recommend creating your own layout component, which will be used as the root of your fragments, exposing a set of properties that you can animate using different objectanimator inside your XML.
The component should look like this:
public class FlippableLayout extends FrameLayout { private FlipEvaluator flipRightInEvaluator; private FlipEvaluator flipRightOutEvaluator; private FlipEvaluator flipLeftInEvaluator; private FlipEvaluator flipLeftOutEvaluator; public FlippableLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } public FlippableLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setCameraDistance(getCameraDistance() * 10); // reduces perspective skewing flipRightInEvaluator = new FlipEvaluator( 1f, .5f, // pivotX/pivotY -1f, 0f, // translationX start/end -180, 0, // rotationY start/end 0f, 1f); // alpha start/end flipRightOutEvaluator = new FlipEvaluator( 0f, .5f, 0f, 1f, 0, 180, 1f, 0f); flipLeftInEvaluator = new FlipEvaluator( .0f, .5f, 1f, 0f, 180, 0, 0f, 1f); flipLeftOutEvaluator = new FlipEvaluator( 1f, .5f, 0f, -1f, 0, -180, 1f, 0f); } public void setFlipRightIn(float value) { evaluateUsing(flipRightInEvaluator, value); } public void setFlipRightOut(float value) { evaluateUsing(flipRightOutEvaluator, value); } public void setFlipLeftIn(float value) { evaluateUsing(flipLeftInEvaluator, value); } public void setFlipLeftOut(float value) { evaluateUsing(flipLeftOutEvaluator, value); } private void evaluateUsing(FlipEvaluator evaluator, float value) { float cappedValue = Math.min(1f, Math.max(0f, value)); setPivotX(getWidth() * evaluator.getPivotX()); setPivotY(getHeight() * evaluator.getPivotY()); setAlpha(evaluator.getAlpha(cappedValue)); setTranslationX(getWidth() * evaluator.getTranslationX(cappedValue)); setRotationY(evaluator.getRotationY(cappedValue)); } private static class FlipEvaluator { private final float pivotX; private final float pivotY; private final float startTranslationX; private final float endTranslationY; private final float startRotationY; private final float endRotationY; private final float startAlpha; private final float endAlpha; /** * Simple evaluator holding all the start/end values for a flip animation. * * @param pivotX value between 0 and 1, where 0 is the left border and 1 is the right border of the target * @param pivotY value between 0 and 1, where 0 is the top border and 1 is the bottom border of the target * @param startTranslationX value between 0 and 1, where 1 is the width of the target * @param endTranslationY value between 0 and 1, where 1 is the width of the target * @param startRotationY value between -180 and 180 * @param endRotationY value between -180 and 180 * @param startAlpha initial alpha * @param endAlpha final alpha */ private FlipEvaluator(float pivotX, float pivotY, float startTranslationX, float endTranslationY, float startRotationY, float endRotationY, float startAlpha, float endAlpha) { this.pivotX = pivotX; this.pivotY = pivotY; this.startTranslationX = startTranslationX; this.endTranslationY = endTranslationY; this.startRotationY = startRotationY; this.endRotationY = endRotationY; this.startAlpha = startAlpha; this.endAlpha = endAlpha; } public float getPivotX() { return pivotX; } public float getPivotY() { return pivotY; } public float getTranslationX(float t) { return startTranslationX + (endTranslationY - startTranslationX) * t; } public float getRotationY(float t) { return startRotationY + (endRotationY - startRotationY) * t; } public float getAlpha(float t) { return t < .5f ? startAlpha : endAlpha; } } }
Your animation files will look like this:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:valueFrom="0" android:valueTo="1" android:propertyName="flipLeftIn" android:interpolator="@android:interpolator/accelerate_decelerate" android:duration="1000" />
Of course, you can change flipLeftIn to flipLeftOut , flipRightIn or flipRightOut to apply the animator to another property.
In Activity you can configure custom animation in a fragment transaction, as usual, by specifying previously defined XML files:
.... getFragmentManager() .beginTransaction() .setCustomAnimations( R.animator.card_flip_right_in, R.animator.card_flip_right_out, R.animator.card_flip_left_in, R.animator.card_flip_left_out) ....

Another approach is to do everything in XML, but setting up rotation / translation using a dimension value defined through XML is not as scalable as the solution shown above.
EDIT To reduce the distance to the camera, you can easily use View.setCameraDistance () in API> 12. I updated the fragment, including this change.
