|
@@ -1,611 +0,0 @@
|
|
|
-package cn.minbb.producttester.controls;
|
|
|
-
|
|
|
-import android.content.Context;
|
|
|
-import android.content.res.TypedArray;
|
|
|
-import android.graphics.Bitmap;
|
|
|
-import android.graphics.Canvas;
|
|
|
-import android.graphics.Color;
|
|
|
-import android.graphics.LinearGradient;
|
|
|
-import android.graphics.Matrix;
|
|
|
-import android.graphics.Paint;
|
|
|
-import android.graphics.Paint.Style;
|
|
|
-import android.graphics.Rect;
|
|
|
-import android.graphics.Shader.TileMode;
|
|
|
-import android.os.Build;
|
|
|
-import android.util.AttributeSet;
|
|
|
-import android.view.View;
|
|
|
-import android.view.ViewGroup;
|
|
|
-
|
|
|
-import cn.minbb.producttester.R;
|
|
|
-
|
|
|
-public class BaseFoldingLayout extends ViewGroup {
|
|
|
-
|
|
|
- public static enum Orientation {
|
|
|
- VERTICAL, HORIZONTAL
|
|
|
- }
|
|
|
-
|
|
|
- private final String FOLDING_VIEW_EXCEPTION_MESSAGE = "Folding Layout can only 1 child at most";
|
|
|
-
|
|
|
- private final float SHADING_ALPHA = 0.8f;
|
|
|
- private final float SHADING_FACTOR = 0.5f;
|
|
|
- private final int DEPTH_CONSTANT = 1500;
|
|
|
- private final int NUM_OF_POLY_POINTS = 8;
|
|
|
-
|
|
|
- private Rect[] mFoldRectArray;
|
|
|
-
|
|
|
- private Matrix[] mMatrix;
|
|
|
-
|
|
|
- protected Orientation mOrientation = Orientation.VERTICAL;
|
|
|
-
|
|
|
- protected float mAnchorFactor = 0;
|
|
|
- private float mFoldFactor = 0;
|
|
|
-
|
|
|
- private int mNumberOfFolds = 2;
|
|
|
-
|
|
|
- private boolean mIsHorizontal = true;
|
|
|
-
|
|
|
- private int mOriginalWidth = 0;
|
|
|
- private int mOriginalHeight = 0;
|
|
|
-
|
|
|
- private float mFoldMaxWidth = 0;
|
|
|
- private float mFoldMaxHeight = 0;
|
|
|
- private float mFoldDrawWidth = 0;
|
|
|
- private float mFoldDrawHeight = 0;
|
|
|
-
|
|
|
- private boolean mIsFoldPrepared = false;
|
|
|
- private boolean mShouldDraw = true;
|
|
|
-
|
|
|
- private Paint mSolidShadow;
|
|
|
- private Paint mGradientShadow;
|
|
|
- private LinearGradient mShadowLinearGradient;
|
|
|
- private Matrix mShadowGradientMatrix;
|
|
|
-
|
|
|
- private float[] mSrc;
|
|
|
- private float[] mDst;
|
|
|
-
|
|
|
- private OnFoldListener mFoldListener;
|
|
|
-
|
|
|
- private float mPreviousFoldFactor = 0;
|
|
|
-
|
|
|
- private Bitmap mFullBitmap;
|
|
|
- private Rect mDstRect;
|
|
|
-
|
|
|
- public BaseFoldingLayout(Context context) {
|
|
|
- super(context);
|
|
|
- }
|
|
|
-
|
|
|
- public BaseFoldingLayout(Context context, AttributeSet attrs) {
|
|
|
- super(context, attrs);
|
|
|
- init(context, attrs);
|
|
|
- }
|
|
|
-
|
|
|
- public BaseFoldingLayout(Context context, AttributeSet attrs, int defStyle) {
|
|
|
- super(context, attrs, defStyle);
|
|
|
- init(context, attrs);
|
|
|
- }
|
|
|
-
|
|
|
- public void init(Context context, AttributeSet attrs) {
|
|
|
- // now style everything!
|
|
|
- TypedArray ta = context.obtainStyledAttributes(attrs,
|
|
|
- R.styleable.FoldingMenu);
|
|
|
- int mFoldNumber = ta.getInt(R.styleable.FoldingMenu_foldNumber,
|
|
|
- mNumberOfFolds);
|
|
|
- if (mFoldNumber > 0 && mFoldNumber < 7) {
|
|
|
- mNumberOfFolds = mFoldNumber;
|
|
|
- } else {
|
|
|
- mNumberOfFolds = 2;
|
|
|
- }
|
|
|
- ta.recycle();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected boolean addViewInLayout(View child, int index,
|
|
|
- LayoutParams params, boolean preventRequestLayout) {
|
|
|
- throwCustomException(getChildCount());
|
|
|
- boolean returnValue = super.addViewInLayout(child, index, params,
|
|
|
- preventRequestLayout);
|
|
|
- return returnValue;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void addView(View child, int index, LayoutParams params) {
|
|
|
- throwCustomException(getChildCount());
|
|
|
- super.addView(child, index, params);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
|
- View child = getChildAt(0);
|
|
|
- measureChild(child, widthMeasureSpec, heightMeasureSpec);
|
|
|
- setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
|
- View child = getChildAt(0);
|
|
|
- child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
|
|
|
- updateFold();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * The custom exception to be thrown so as to limit the number of views in
|
|
|
- * this layout to at most one.
|
|
|
- */
|
|
|
- private class NumberOfFoldingLayoutChildrenException extends
|
|
|
- RuntimeException {
|
|
|
- /**
|
|
|
- *
|
|
|
- */
|
|
|
- private static final long serialVersionUID = 1L;
|
|
|
-
|
|
|
- public NumberOfFoldingLayoutChildrenException(String message) {
|
|
|
- super(message);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Throws an exception if the number of views added to this layout exceeds
|
|
|
- * one.
|
|
|
- */
|
|
|
- private void throwCustomException(int numOfChildViews) {
|
|
|
- if (numOfChildViews == 1) {
|
|
|
- throw new NumberOfFoldingLayoutChildrenException(
|
|
|
- FOLDING_VIEW_EXCEPTION_MESSAGE);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void setFoldListener(OnFoldListener foldListener) {
|
|
|
- mFoldListener = foldListener;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the fold factor of the folding view and updates all the
|
|
|
- * corresponding matrices and values to account for the new fold factor.
|
|
|
- * Once that is complete, it redraws itself with the new fold.
|
|
|
- */
|
|
|
- public void setFoldFactor(float foldFactor) {
|
|
|
- if (foldFactor != mFoldFactor) {
|
|
|
- mFoldFactor = foldFactor;
|
|
|
- calculateMatrices();
|
|
|
- invalidate();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public void setOrientation(Orientation orientation) {
|
|
|
- if (orientation != mOrientation) {
|
|
|
- mOrientation = orientation;
|
|
|
- updateFold();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void setAnchorFactor(float anchorFactor) {
|
|
|
- if (anchorFactor != mAnchorFactor) {
|
|
|
- mAnchorFactor = anchorFactor;
|
|
|
- updateFold();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void setNumberOfFolds(int numberOfFolds) {
|
|
|
- if (numberOfFolds != mNumberOfFolds) {
|
|
|
- mNumberOfFolds = numberOfFolds;
|
|
|
- updateFold();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public float getAnchorFactor() {
|
|
|
- return mAnchorFactor;
|
|
|
- }
|
|
|
-
|
|
|
- public Orientation getOrientation() {
|
|
|
- return mOrientation;
|
|
|
- }
|
|
|
-
|
|
|
- public float getFoldFactor() {
|
|
|
- return mFoldFactor;
|
|
|
- }
|
|
|
-
|
|
|
- public int getNumberOfFolds() {
|
|
|
- return mNumberOfFolds;
|
|
|
- }
|
|
|
-
|
|
|
- private void updateFold() {
|
|
|
- prepareFold(mOrientation, mAnchorFactor, mNumberOfFolds);
|
|
|
- calculateMatrices();
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method is called in order to update the fold's orientation, anchor
|
|
|
- * point and number of folds. This creates the necessary setup in order to
|
|
|
- * prepare the layout for a fold with the specified parameters. Some of the
|
|
|
- * dimensions required for the folding transformation are also acquired
|
|
|
- * here.
|
|
|
- * <p>
|
|
|
- * After this method is called, it will be in a completely unfolded state by
|
|
|
- * default.
|
|
|
- */
|
|
|
- private void prepareFold(Orientation orientation, float anchorFactor,
|
|
|
- int numberOfFolds) {
|
|
|
-
|
|
|
- mSrc = new float[NUM_OF_POLY_POINTS];
|
|
|
- mDst = new float[NUM_OF_POLY_POINTS];
|
|
|
-
|
|
|
- mDstRect = new Rect();
|
|
|
-
|
|
|
- mFoldFactor = 0;
|
|
|
- mPreviousFoldFactor = 0;
|
|
|
-
|
|
|
- mIsFoldPrepared = false;
|
|
|
-
|
|
|
- mSolidShadow = new Paint();
|
|
|
- mGradientShadow = new Paint();
|
|
|
-
|
|
|
- mOrientation = orientation;
|
|
|
- mIsHorizontal = (orientation == Orientation.HORIZONTAL);
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- mShadowLinearGradient = new LinearGradient(0, 0, SHADING_FACTOR, 0,
|
|
|
- Color.BLACK, Color.TRANSPARENT, TileMode.CLAMP);
|
|
|
- } else {
|
|
|
- mShadowLinearGradient = new LinearGradient(0, 0, 0, SHADING_FACTOR,
|
|
|
- Color.BLACK, Color.TRANSPARENT, TileMode.CLAMP);
|
|
|
- }
|
|
|
-
|
|
|
- mGradientShadow.setStyle(Style.FILL);
|
|
|
- mGradientShadow.setShader(mShadowLinearGradient);
|
|
|
- mShadowGradientMatrix = new Matrix();
|
|
|
-
|
|
|
- mAnchorFactor = anchorFactor;
|
|
|
- mNumberOfFolds = numberOfFolds;
|
|
|
-
|
|
|
- mOriginalWidth = getMeasuredWidth();
|
|
|
- mOriginalHeight = getMeasuredHeight();
|
|
|
-
|
|
|
- mFoldRectArray = new Rect[mNumberOfFolds];
|
|
|
- mMatrix = new Matrix[mNumberOfFolds];
|
|
|
-
|
|
|
- for (int x = 0; x < mNumberOfFolds; x++) {
|
|
|
- mMatrix[x] = new Matrix();
|
|
|
- }
|
|
|
-
|
|
|
- int h = mOriginalHeight;
|
|
|
- int w = mOriginalWidth;
|
|
|
-
|
|
|
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR2 && h != 0 && w != 0) {
|
|
|
- mFullBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
|
|
- Canvas canvas = new Canvas(mFullBitmap);
|
|
|
- getChildAt(0).draw(canvas);
|
|
|
- }
|
|
|
-
|
|
|
- int delta = Math.round(mIsHorizontal ? ((float) w)
|
|
|
- / ((float) mNumberOfFolds) : ((float) h)
|
|
|
- / ((float) mNumberOfFolds));
|
|
|
-
|
|
|
- /*
|
|
|
- * Loops through the number of folds and segments the full layout into a
|
|
|
- * number of smaller equal components. If the number of folds is odd,
|
|
|
- * then one of the components will be smaller than all the rest. Note
|
|
|
- * that deltap below handles the calculation for an odd number of folds.
|
|
|
- */
|
|
|
- for (int x = 0; x < mNumberOfFolds; x++) {
|
|
|
- if (mIsHorizontal) {
|
|
|
- int deltap = (x + 1) * delta > w ? w - x * delta : delta;
|
|
|
- mFoldRectArray[x] = new Rect(x * delta, 0, x * delta + deltap,
|
|
|
- h);
|
|
|
- } else {
|
|
|
- int deltap = (x + 1) * delta > h ? h - x * delta : delta;
|
|
|
- mFoldRectArray[x] = new Rect(0, x * delta, w, x * delta
|
|
|
- + deltap);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- mFoldMaxHeight = h;
|
|
|
- mFoldMaxWidth = delta;
|
|
|
- } else {
|
|
|
- mFoldMaxHeight = delta;
|
|
|
- mFoldMaxWidth = w;
|
|
|
- }
|
|
|
-
|
|
|
- mIsFoldPrepared = true;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Calculates the transformation matrices used to draw each of the separate
|
|
|
- * folding segments from this view.
|
|
|
- */
|
|
|
- private void calculateMatrices() {
|
|
|
-
|
|
|
- mShouldDraw = true;
|
|
|
-
|
|
|
- if (!mIsFoldPrepared) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * If the fold factor is 1 than the folding view should not be seen and
|
|
|
- * the canvas can be left completely empty.
|
|
|
- */
|
|
|
- if (mFoldFactor == 1) {
|
|
|
- mShouldDraw = false;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-// if (mFoldFactor == 0 && mPreviousFoldFactor > 0
|
|
|
-// && mFoldListener != null) {
|
|
|
-//
|
|
|
-// mFoldListener.onEndFold(mFoldFactor);
|
|
|
-// }else if (mPreviousFoldFactor == 0 && mFoldFactor > 0
|
|
|
-// && mFoldListener != null) {
|
|
|
-//
|
|
|
-// mFoldListener.onStartFold(mFoldFactor);
|
|
|
-// } else if(mFoldListener != null) {
|
|
|
-// mFoldListener.onFoldingState(mFoldFactor);
|
|
|
-// }
|
|
|
-
|
|
|
- if (mFoldFactor > 0.9f && mFoldFactor > mPreviousFoldFactor
|
|
|
- && mFoldListener != null) {
|
|
|
-
|
|
|
- mFoldListener.onEndFold(mFoldFactor);
|
|
|
- } else if (mFoldFactor < 0.1f && mFoldFactor < mPreviousFoldFactor
|
|
|
- && mFoldListener != null) {
|
|
|
-
|
|
|
- mFoldListener.onStartFold(mFoldFactor);
|
|
|
- } else if (mFoldListener != null) {
|
|
|
-
|
|
|
- mFoldListener.onFoldingState(mFoldFactor, mFoldDrawHeight);
|
|
|
- }
|
|
|
-
|
|
|
-// if(mFoldFactor == 0 && mFoldListener != null) {
|
|
|
-// mFoldListener.onStartFold(mFoldFactor);
|
|
|
-// } else if(mFoldFactor == 1 && mFoldListener != null) {
|
|
|
-// mFoldListener.onEndFold(mFoldFactor);
|
|
|
-// } else {
|
|
|
-// mFoldListener.onFoldingState(mFoldFactor);
|
|
|
-// }
|
|
|
-
|
|
|
- mPreviousFoldFactor = mFoldFactor;
|
|
|
-
|
|
|
- /*
|
|
|
- * Reset all the transformation matrices back to identity before
|
|
|
- * computing the new transformation
|
|
|
- */
|
|
|
- for (int x = 0; x < mNumberOfFolds; x++) {
|
|
|
- mMatrix[x].reset();
|
|
|
- }
|
|
|
-
|
|
|
- float cTranslationFactor = 1 - mFoldFactor;
|
|
|
-
|
|
|
- float translatedDistance = mIsHorizontal ? mOriginalWidth
|
|
|
- * cTranslationFactor : mOriginalHeight * cTranslationFactor;
|
|
|
-
|
|
|
- float translatedDistancePerFold = Math.round(translatedDistance
|
|
|
- / mNumberOfFolds);
|
|
|
-
|
|
|
- /*
|
|
|
- * For an odd number of folds, the rounding error may cause the
|
|
|
- * translatedDistancePerFold to be grater than the max fold width or
|
|
|
- * height.
|
|
|
- */
|
|
|
- mFoldDrawWidth = mFoldMaxWidth < translatedDistancePerFold ? translatedDistancePerFold
|
|
|
- : mFoldMaxWidth;
|
|
|
- mFoldDrawHeight = mFoldMaxHeight < translatedDistancePerFold ? translatedDistancePerFold
|
|
|
- : mFoldMaxHeight;
|
|
|
-
|
|
|
- float translatedDistanceFoldSquared = translatedDistancePerFold
|
|
|
- * translatedDistancePerFold;
|
|
|
-
|
|
|
- /*
|
|
|
- * Calculate the depth of the fold into the screen using pythagorean
|
|
|
- * theorem.
|
|
|
- */
|
|
|
- float depth = mIsHorizontal ? (float) Math
|
|
|
- .sqrt((double) (mFoldDrawWidth * mFoldDrawWidth - translatedDistanceFoldSquared))
|
|
|
- : (float) Math
|
|
|
- .sqrt((double) (mFoldDrawHeight * mFoldDrawHeight - translatedDistanceFoldSquared));
|
|
|
-
|
|
|
- /*
|
|
|
- * The size of some object is always inversely proportional to the
|
|
|
- * distance it is away from the viewpoint. The constant can be varied to
|
|
|
- * to affect the amount of perspective.
|
|
|
- */
|
|
|
- float scaleFactor = DEPTH_CONSTANT / (DEPTH_CONSTANT + depth);
|
|
|
-
|
|
|
- float scaledWidth, scaledHeight, bottomScaledPoint, topScaledPoint, rightScaledPoint, leftScaledPoint;
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- scaledWidth = mFoldDrawWidth * cTranslationFactor;
|
|
|
- scaledHeight = mFoldDrawHeight * scaleFactor;
|
|
|
- } else {
|
|
|
- scaledWidth = mFoldDrawWidth * scaleFactor;
|
|
|
- scaledHeight = mFoldDrawHeight * cTranslationFactor;
|
|
|
- }
|
|
|
-
|
|
|
- topScaledPoint = (mFoldDrawHeight - scaledHeight) / 2.0f;
|
|
|
- bottomScaledPoint = topScaledPoint + scaledHeight;
|
|
|
-
|
|
|
- leftScaledPoint = (mFoldDrawWidth - scaledWidth) / 2.0f;
|
|
|
- rightScaledPoint = leftScaledPoint + scaledWidth;
|
|
|
-
|
|
|
- float anchorPoint = mIsHorizontal ? mAnchorFactor * mOriginalWidth
|
|
|
- : mAnchorFactor * mOriginalHeight;
|
|
|
-
|
|
|
- /* The fold along which the anchor point is located. */
|
|
|
- float midFold = mIsHorizontal ? (anchorPoint / mFoldDrawWidth)
|
|
|
- : anchorPoint / mFoldDrawHeight;
|
|
|
-
|
|
|
- mSrc[0] = 0;
|
|
|
- mSrc[1] = 0;
|
|
|
- mSrc[2] = 0;
|
|
|
- mSrc[3] = mFoldDrawHeight;
|
|
|
- mSrc[4] = mFoldDrawWidth;
|
|
|
- mSrc[5] = 0;
|
|
|
- mSrc[6] = mFoldDrawWidth;
|
|
|
- mSrc[7] = mFoldDrawHeight;
|
|
|
-
|
|
|
- /*
|
|
|
- * Computes the transformation matrix for each fold using the values
|
|
|
- * calculated above.
|
|
|
- */
|
|
|
- for (int x = 0; x < mNumberOfFolds; x++) {
|
|
|
-
|
|
|
- boolean isEven = (x % 2 == 0);
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- mDst[0] = (anchorPoint > x * mFoldDrawWidth) ? anchorPoint
|
|
|
- + (x - midFold) * scaledWidth : anchorPoint
|
|
|
- - (midFold - x) * scaledWidth;
|
|
|
- mDst[1] = isEven ? 0 : topScaledPoint;
|
|
|
- mDst[2] = mDst[0];
|
|
|
- mDst[3] = isEven ? mFoldDrawHeight : bottomScaledPoint;
|
|
|
- mDst[4] = (anchorPoint > (x + 1) * mFoldDrawWidth) ? anchorPoint
|
|
|
- + (x + 1 - midFold) * scaledWidth
|
|
|
- : anchorPoint - (midFold - x - 1) * scaledWidth;
|
|
|
- mDst[5] = isEven ? topScaledPoint : 0;
|
|
|
- mDst[6] = mDst[4];
|
|
|
- mDst[7] = isEven ? bottomScaledPoint : mFoldDrawHeight;
|
|
|
-
|
|
|
- } else {
|
|
|
- mDst[0] = isEven ? 0 : leftScaledPoint;
|
|
|
- mDst[1] = (anchorPoint > x * mFoldDrawHeight) ? anchorPoint
|
|
|
- + (x - midFold) * scaledHeight : anchorPoint
|
|
|
- - (midFold - x) * scaledHeight;
|
|
|
- mDst[2] = isEven ? leftScaledPoint : 0;
|
|
|
- mDst[3] = (anchorPoint > (x + 1) * mFoldDrawHeight) ? anchorPoint
|
|
|
- + (x + 1 - midFold) * scaledHeight
|
|
|
- : anchorPoint - (midFold - x - 1) * scaledHeight;
|
|
|
- mDst[4] = isEven ? mFoldDrawWidth : rightScaledPoint;
|
|
|
- mDst[5] = mDst[1];
|
|
|
- mDst[6] = isEven ? rightScaledPoint : mFoldDrawWidth;
|
|
|
- mDst[7] = mDst[3];
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Pixel fractions are present for odd number of folds which need to
|
|
|
- * be rounded off here.
|
|
|
- */
|
|
|
- for (int y = 0; y < 8; y++) {
|
|
|
- mDst[y] = Math.round(mDst[y]);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * If it so happens that any of the folds have reached a point where
|
|
|
- * the width or height of that fold is 0, then nothing needs to be
|
|
|
- * drawn onto the canvas because the view is essentially completely
|
|
|
- * folded.
|
|
|
- */
|
|
|
- if (mIsHorizontal) {
|
|
|
- if (mDst[4] <= mDst[0] || mDst[6] <= mDst[2]) {
|
|
|
- mShouldDraw = false;
|
|
|
- return;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (mDst[3] <= mDst[1] || mDst[7] <= mDst[5]) {
|
|
|
- mShouldDraw = false;
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Sets the shadow and bitmap transformation matrices. */
|
|
|
- mMatrix[x].setPolyToPoly(mSrc, 0, mDst, 0, NUM_OF_POLY_POINTS / 2);
|
|
|
- }
|
|
|
- /*
|
|
|
- * The shadows on the folds are split into two parts: Solid shadows and
|
|
|
- * gradients. Every other fold has a solid shadow which overlays the
|
|
|
- * whole fold. Similarly, the folds in between these alternating folds
|
|
|
- * also have an overlaying shadow. However, it is a gradient that takes
|
|
|
- * up part of the fold as opposed to a solid shadow overlaying the whole
|
|
|
- * fold.
|
|
|
- */
|
|
|
-
|
|
|
- /* Solid shadow paint object. */
|
|
|
- int alpha = (int) (mFoldFactor * 255 * SHADING_ALPHA);
|
|
|
-
|
|
|
- mSolidShadow.setColor(Color.argb(alpha, 0, 0, 0));
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- mShadowGradientMatrix.setScale(mFoldDrawWidth, 1);
|
|
|
- mShadowLinearGradient.setLocalMatrix(mShadowGradientMatrix);
|
|
|
- } else {
|
|
|
- mShadowGradientMatrix.setScale(1, mFoldDrawHeight);
|
|
|
- mShadowLinearGradient.setLocalMatrix(mShadowGradientMatrix);
|
|
|
- }
|
|
|
-
|
|
|
- mGradientShadow.setAlpha(alpha);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void dispatchDraw(Canvas canvas) {
|
|
|
- /**
|
|
|
- * If prepareFold has not been called or if preparation has not
|
|
|
- * completed yet, then no custom drawing will take place so only need to
|
|
|
- * invoke super's onDraw and return.
|
|
|
- */
|
|
|
- if (!mIsFoldPrepared || mFoldFactor == 0) {
|
|
|
- super.dispatchDraw(canvas);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!mShouldDraw) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- Rect src;
|
|
|
- /*
|
|
|
- * Draws the bitmaps and shadows on the canvas with the appropriate
|
|
|
- * transformations.
|
|
|
- */
|
|
|
- for (int x = 0; x < mNumberOfFolds; x++) {
|
|
|
-
|
|
|
- src = mFoldRectArray[x];
|
|
|
- /* The canvas is saved and restored for every individual fold */
|
|
|
- canvas.save();
|
|
|
-
|
|
|
- /*
|
|
|
- * Concatenates the canvas with the transformation matrix for the
|
|
|
- * the segment of the view corresponding to the actual image being
|
|
|
- * displayed.
|
|
|
- */
|
|
|
- canvas.concat(mMatrix[x]);
|
|
|
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
|
|
- mDstRect.set(0, 0, src.width(), src.height());
|
|
|
- canvas.drawBitmap(mFullBitmap, src, mDstRect, null);
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * The same transformation matrix is used for both the shadow
|
|
|
- * and the image segment. The canvas is clipped to account for
|
|
|
- * the size of each fold and is translated so they are drawn in
|
|
|
- * the right place. The shadow is then drawn on top of the
|
|
|
- * different folds using the sametransformation matrix.
|
|
|
- */
|
|
|
- canvas.clipRect(0, 0, src.right - src.left, src.bottom
|
|
|
- - src.top);
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- canvas.translate(-src.left, 0);
|
|
|
- } else {
|
|
|
- canvas.translate(0, -src.top);
|
|
|
- }
|
|
|
-
|
|
|
- super.dispatchDraw(canvas);
|
|
|
-
|
|
|
- if (mIsHorizontal) {
|
|
|
- canvas.translate(src.left, 0);
|
|
|
- } else {
|
|
|
- canvas.translate(0, src.top);
|
|
|
- }
|
|
|
- }
|
|
|
- /* Draws the shadows corresponding to this specific fold. */
|
|
|
- if (x % 2 == 0) {
|
|
|
- canvas.drawRect(0, 0, mFoldDrawWidth, mFoldDrawHeight,
|
|
|
- mSolidShadow);
|
|
|
- } else {
|
|
|
- canvas.drawRect(0, 0, mFoldDrawWidth, mFoldDrawHeight,
|
|
|
- mGradientShadow);
|
|
|
- }
|
|
|
-
|
|
|
- canvas.restore();
|
|
|
- }
|
|
|
- }
|
|
|
-}
|