Java tutorial
package com.insalyon.les24heures.JazzyViewPager; /** * https://github.com/jfeinstein10/JazzyViewPager * * Copyright 2013 Jeremy Feinstein 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. */ import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Camera; import android.graphics.Color; import android.graphics.Matrix; import android.os.Build; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import com.insalyon.les24heures.R; import com.nineoldandroids.view.ViewHelper; import java.util.HashMap; import java.util.LinkedHashMap; public class JazzyViewPager extends ViewPager { public static final String TAG = "JazzyViewPager"; private static final float SCALE_MAX = 0.5f; private static final float ZOOM_MAX = 0.5f; private static final float ROT_MAX = 15.0f; private static final boolean API_11; static { API_11 = Build.VERSION.SDK_INT >= 11; } public static int sOutlineColor = Color.WHITE; private boolean mEnabled = true; private boolean mFadeEnabled = false; private boolean mOutlineEnabled = false; private TransitionEffect mEffect = TransitionEffect.Standard; private HashMap<Integer, Object> mObjs = new LinkedHashMap<Integer, Object>(); private State mState; private int oldPage; private View mLeft; private View mRight; private float mRot; private float mTrans; private float mScale; private Matrix mMatrix = new Matrix(); private Camera mCamera = new Camera(); private float[] mTempFloat2 = new float[2]; public JazzyViewPager(Context context) { this(context, null); } @SuppressWarnings("incomplete-switch") public JazzyViewPager(Context context, AttributeSet attrs) { super(context, attrs); setClipChildren(false); // now style everything! TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.JazzyViewPager); int effect = ta.getInt(R.styleable.JazzyViewPager_style, 0); String[] transitions = getResources().getStringArray(R.array.jazzy_effects); setTransitionEffect(TransitionEffect.valueOf(transitions[effect])); setFadeEnabled(ta.getBoolean(R.styleable.JazzyViewPager_fadeEnabled, false)); setOutlineEnabled(ta.getBoolean(R.styleable.JazzyViewPager_outlineEnabled, false)); setOutlineColor(ta.getColor(R.styleable.JazzyViewPager_outlineColor, Color.WHITE)); switch (mEffect) { case Stack: case ZoomOut: setFadeEnabled(true); } ta.recycle(); } public void setTransitionEffect(TransitionEffect effect) { mEffect = effect; // reset(); } public void setPagingEnabled(boolean enabled) { mEnabled = enabled; } public boolean getFadeEnabled() { return mFadeEnabled; } public void setFadeEnabled(boolean enabled) { mFadeEnabled = enabled; } public void setOutlineEnabled(boolean enabled) { mOutlineEnabled = enabled; wrapWithOutlines(); } public void setOutlineColor(int color) { sOutlineColor = color; } private void wrapWithOutlines() { for (int i = 0; i < getChildCount(); i++) { View v = getChildAt(i); if (!(v instanceof OutlineContainer)) { removeView(v); super.addView(wrapChild(v), i); } } } private View wrapChild(View child) { if (!mOutlineEnabled || child instanceof OutlineContainer) return child; OutlineContainer out = new OutlineContainer(getContext()); out.setLayoutParams(generateDefaultLayoutParams()); child.setLayoutParams( new OutlineContainer.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); out.addView(child); return out; } public void addView(View child) { super.addView(wrapChild(child)); } public void addView(View child, int index) { super.addView(wrapChild(child), index); } public void addView(View child, LayoutParams params) { super.addView(wrapChild(child), params); } public void addView(View child, int width, int height) { super.addView(wrapChild(child), width, height); } public void addView(View child, int index, LayoutParams params) { super.addView(wrapChild(child), index, params); } // public void reset() { // resetPrivate(); // int curr = getCurrentItem(); // onPageScrolled(curr, 0.0f, 0); //} // //private void resetPrivate() { // for (int i = 0; i < getChildCount(); i++) { // View v = getChildAt(i); // // ViewHelper.setRotation(v, -ViewHelper.getRotation(v)); // // ViewHelper.setRotationX(v, -ViewHelper.getRotationX(v)); // // ViewHelper.setRotationY(v, -ViewHelper.getRotationY(v)); // // // // ViewHelper.setTranslationX(v, -ViewHelper.getTranslationX(v)); // // ViewHelper.setTranslationY(v, -ViewHelper.getTranslationY(v)); // // ViewHelper.setRotation(v, 0); // ViewHelper.setRotationX(v, 0); // ViewHelper.setRotationY(v, 0); // // ViewHelper.setTranslationX(v, 0); // ViewHelper.setTranslationY(v, 0); // // ViewHelper.setAlpha(v, 1.0f); // // ViewHelper.setScaleX(v, 1.0f); // ViewHelper.setScaleY(v, 1.0f); // // ViewHelper.setPivotX(v, 0); // ViewHelper.setPivotY(v, 0); // // logState(v, "Child " + i); // } //} @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { return mEnabled ? super.onInterceptTouchEvent(arg0) : false; } private void logState(View v, String title) { Log.v(TAG, title + ": ROT (" + ViewHelper.getRotation(v) + ", " + ViewHelper.getRotationX(v) + ", " + ViewHelper.getRotationY(v) + "), TRANS (" + ViewHelper.getTranslationX(v) + ", " + ViewHelper.getTranslationY(v) + "), SCALE (" + ViewHelper.getScaleX(v) + ", " + ViewHelper.getScaleY(v) + "), ALPHA " + ViewHelper.getAlpha(v)); } protected void animateScroll(int position, float positionOffset) { if (mState != State.IDLE) { mRot = (float) (1 - Math.cos(2 * Math.PI * positionOffset)) / 2 * 30.0f; ViewHelper.setRotationY(this, mState == State.GOING_RIGHT ? mRot : -mRot); ViewHelper.setPivotX(this, getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(this, getMeasuredHeight() * 0.5f); } } protected void animateTablet(View left, View right, float positionOffset) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mRot = 30.0f * positionOffset; mTrans = getOffsetXForRotation(mRot, left.getMeasuredWidth(), left.getMeasuredHeight()); ViewHelper.setPivotX(left, left.getMeasuredWidth() / 2); ViewHelper.setPivotY(left, left.getMeasuredHeight() / 2); ViewHelper.setTranslationX(left, mTrans); ViewHelper.setRotationY(left, mRot); logState(left, "Left"); } if (right != null) { manageLayer(right, true); mRot = -30.0f * (1 - positionOffset); mTrans = getOffsetXForRotation(mRot, right.getMeasuredWidth(), right.getMeasuredHeight()); ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f); ViewHelper.setTranslationX(right, mTrans); ViewHelper.setRotationY(right, mRot); logState(right, "Right"); } } } private void animateCube(View left, View right, float positionOffset, boolean in) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mRot = (in ? 90.0f : -90.0f) * positionOffset; ViewHelper.setPivotX(left, left.getMeasuredWidth()); ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f); ViewHelper.setRotationY(left, mRot); } if (right != null) { manageLayer(right, true); mRot = -(in ? 90.0f : -90.0f) * (1 - positionOffset); ViewHelper.setPivotX(right, 0); ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f); ViewHelper.setRotationY(right, mRot); } } } private void animateAccordion(View left, View right, float positionOffset) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); ViewHelper.setPivotX(left, left.getMeasuredWidth()); ViewHelper.setPivotY(left, 0); ViewHelper.setScaleX(left, 1 - positionOffset); } if (right != null) { manageLayer(right, true); ViewHelper.setPivotX(right, 0); ViewHelper.setPivotY(right, 0); ViewHelper.setScaleX(right, positionOffset); } } } private void animateZoom(View left, View right, float positionOffset, boolean in) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mScale = in ? ZOOM_MAX + (1 - ZOOM_MAX) * (1 - positionOffset) : 1 + ZOOM_MAX - ZOOM_MAX * (1 - positionOffset); ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f); ViewHelper.setScaleX(left, mScale); ViewHelper.setScaleY(left, mScale); } if (right != null) { manageLayer(right, true); mScale = in ? ZOOM_MAX + (1 - ZOOM_MAX) * positionOffset : 1 + ZOOM_MAX - ZOOM_MAX * positionOffset; ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f); ViewHelper.setScaleX(right, mScale); ViewHelper.setScaleY(right, mScale); } } } private void animateRotate(View left, View right, float positionOffset, boolean up) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mRot = (up ? 1 : -1) * (ROT_MAX * positionOffset); mTrans = (up ? -1 : 1) * (float) (getMeasuredHeight() - getMeasuredHeight() * Math.cos(mRot * Math.PI / 180.0f)); ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(left, up ? 0 : left.getMeasuredHeight()); ViewHelper.setTranslationY(left, mTrans); ViewHelper.setRotation(left, mRot); } if (right != null) { manageLayer(right, true); mRot = (up ? 1 : -1) * (-ROT_MAX + ROT_MAX * positionOffset); mTrans = (up ? -1 : 1) * (float) (getMeasuredHeight() - getMeasuredHeight() * Math.cos(mRot * Math.PI / 180.0f)); ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(right, up ? 0 : right.getMeasuredHeight()); ViewHelper.setTranslationY(right, mTrans); ViewHelper.setRotation(right, mRot); } } } private void animateFlipHorizontal(View left, View right, float positionOffset, int positionOffsetPixels) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mRot = 180.0f * positionOffset; if (mRot > 90.0f) { left.setVisibility(View.INVISIBLE); } else { if (left.getVisibility() == View.INVISIBLE) left.setVisibility(View.VISIBLE); mTrans = positionOffsetPixels; ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f); ViewHelper.setTranslationX(left, mTrans); ViewHelper.setRotationY(left, mRot); } } if (right != null) { manageLayer(right, true); mRot = -180.0f * (1 - positionOffset); if (mRot < -90.0f) { right.setVisibility(View.INVISIBLE); } else { if (right.getVisibility() == View.INVISIBLE) right.setVisibility(View.VISIBLE); mTrans = -getWidth() - getPageMargin() + positionOffsetPixels; ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f); ViewHelper.setTranslationX(right, mTrans); ViewHelper.setRotationY(right, mRot); } } } } private void animateFlipVertical(View left, View right, float positionOffset, int positionOffsetPixels) { if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); mRot = 180.0f * positionOffset; if (mRot > 90.0f) { left.setVisibility(View.INVISIBLE); } else { if (left.getVisibility() == View.INVISIBLE) left.setVisibility(View.VISIBLE); mTrans = positionOffsetPixels; ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f); ViewHelper.setTranslationX(left, mTrans); ViewHelper.setRotationX(left, mRot); } } if (right != null) { manageLayer(right, true); mRot = -180.0f * (1 - positionOffset); if (mRot < -90.0f) { right.setVisibility(View.INVISIBLE); } else { if (right.getVisibility() == View.INVISIBLE) right.setVisibility(View.VISIBLE); mTrans = -getWidth() - getPageMargin() + positionOffsetPixels; ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f); ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f); ViewHelper.setTranslationX(right, mTrans); ViewHelper.setRotationX(right, mRot); } } } } protected void animateStack(View left, View right, float positionOffset, int positionOffsetPixels) { if (mState != State.IDLE) { if (right != null) { manageLayer(right, true); mScale = (1 - SCALE_MAX) * positionOffset + SCALE_MAX; mTrans = -getWidth() - getPageMargin() + positionOffsetPixels; ViewHelper.setScaleX(right, mScale); ViewHelper.setScaleY(right, mScale); ViewHelper.setTranslationX(right, mTrans); } if (left != null) { left.bringToFront(); } } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void manageLayer(View v, boolean enableHardware) { if (!API_11) return; int layerType = enableHardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE; if (layerType != v.getLayerType()) v.setLayerType(layerType, null); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void disableHardwareLayer() { if (!API_11) return; View v; for (int i = 0; i < getChildCount(); i++) { v = getChildAt(i); if (v.getLayerType() != View.LAYER_TYPE_NONE) v.setLayerType(View.LAYER_TYPE_NONE, null); } } protected float getOffsetXForRotation(float degrees, int width, int height) { mMatrix.reset(); mCamera.save(); mCamera.rotateY(Math.abs(degrees)); mCamera.getMatrix(mMatrix); mCamera.restore(); mMatrix.preTranslate(-width * 0.5f, -height * 0.5f); mMatrix.postTranslate(width * 0.5f, height * 0.5f); mTempFloat2[0] = width; mTempFloat2[1] = height; mMatrix.mapPoints(mTempFloat2); return (width - mTempFloat2[0]) * (degrees > 0.0f ? 1.0f : -1.0f); } protected void animateFade(View left, View right, float positionOffset) { if (left != null) { ViewHelper.setAlpha(left, 1 - positionOffset); } if (right != null) { ViewHelper.setAlpha(right, positionOffset); } } protected void animateOutline(View left, View right) { if (!(left instanceof OutlineContainer)) return; if (mState != State.IDLE) { if (left != null) { manageLayer(left, true); ((OutlineContainer) left).setOutlineAlpha(1.0f); } if (right != null) { manageLayer(right, true); ((OutlineContainer) right).setOutlineAlpha(1.0f); } } else { if (left != null) ((OutlineContainer) left).start(); if (right != null) ((OutlineContainer) right).start(); } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (mState == State.IDLE && positionOffset > 0) { oldPage = getCurrentItem(); mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT; } boolean goingRight = position == oldPage; if (mState == State.GOING_RIGHT && !goingRight) mState = State.GOING_LEFT; else if (mState == State.GOING_LEFT && goingRight) mState = State.GOING_RIGHT; float effectOffset = isSmall(positionOffset) ? 0 : positionOffset; // mLeft = getChildAt(position); // mRight = getChildAt(position+1); mLeft = findViewFromObject(position); mRight = findViewFromObject(position + 1); if (mFadeEnabled) animateFade(mLeft, mRight, effectOffset); if (mOutlineEnabled) animateOutline(mLeft, mRight); switch (mEffect) { case Standard: break; case Tablet: animateTablet(mLeft, mRight, effectOffset); break; case CubeIn: animateCube(mLeft, mRight, effectOffset, true); break; case CubeOut: animateCube(mLeft, mRight, effectOffset, false); break; case FlipVertical: animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels); break; case FlipHorizontal: animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels); case Stack: animateStack(mLeft, mRight, effectOffset, positionOffsetPixels); break; case ZoomIn: animateZoom(mLeft, mRight, effectOffset, true); break; case ZoomOut: animateZoom(mLeft, mRight, effectOffset, false); break; case RotateUp: animateRotate(mLeft, mRight, effectOffset, true); break; case RotateDown: animateRotate(mLeft, mRight, effectOffset, false); break; case Accordion: animateAccordion(mLeft, mRight, effectOffset); break; } super.onPageScrolled(position, positionOffset, positionOffsetPixels); if (effectOffset == 0) { disableHardwareLayer(); mState = State.IDLE; } } private boolean isSmall(float positionOffset) { return Math.abs(positionOffset) < 0.0001; } public void setObjectForPosition(Object obj, int position) { mObjs.put(Integer.valueOf(position), obj); } public View findViewFromObject(int position) { Object o = mObjs.get(Integer.valueOf(position)); if (o == null) { return null; } PagerAdapter a = getAdapter(); View v; for (int i = 0; i < getChildCount(); i++) { v = getChildAt(i); if (a.isViewFromObject(v, o)) return v; } return null; } public enum TransitionEffect { Standard, Tablet, CubeIn, CubeOut, FlipVertical, FlipHorizontal, Stack, ZoomIn, ZoomOut, RotateUp, RotateDown, Accordion } private enum State { IDLE, GOING_LEFT, GOING_RIGHT } }