package moe.feng.nhentai.view.flow;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.Transformation;
import moe.feng.nhentai.R;
import moe.feng.nhentai.view.TwoWayGallery;
/**
* Created by HelloCsl(cslgogogo@gmail.com) on 2015/9/28 0028.
*/
class CoverFlow extends TwoWayGallery {
private final String TAG = this.getClass().getSimpleName();
private final boolean DEBUG = true;
private final float DEFAULT_UNSELECTED_SCALE = 1.0f;
private final float DEFAULT_COVERAGE = 0f;
private Matrix mHorizontalMatrix, mVerticalMatrix;
private float mUnselectedScale = DEFAULT_UNSELECTED_SCALE;
private float mCoverage = DEFAULT_COVERAGE;
public CoverFlow(Context context) {
super(context);
setStaticTransformationsEnabled(true);
}
public CoverFlow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CoverFlow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CoverFlow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
setStaticTransformationsEnabled(true);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.CoverFlow);
mUnselectedScale = a.getFloat(R.styleable.CoverFlow_unselectedScale, DEFAULT_UNSELECTED_SCALE);
mCoverage = a.getFloat(R.styleable.CoverFlow_coverage, DEFAULT_COVERAGE);
a.recycle();
}
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
super.getChildStaticTransformation(child, t);
if (getOrientation() == VERTICAL) {
final int coverFlowCenter = getVerticalCenterOfGallery();
final int childWidth = child.getWidth();
final int childHeight = child.getHeight();
final int childCenter = child.getTop() + childHeight / 2;
float w = childHeight;
float distance = Math.abs(childCenter - coverFlowCenter);
boolean bottomOfCenter = childCenter - coverFlowCenter >= 0 ? true : false;
t.clear();
mVerticalMatrix = t.getMatrix();
//线性变化
float effectAmount = 1.0f * distance * (mUnselectedScale - 1) / w + 1;
float alpha = 1.0f * distance * (getUnselectedAlpha() - 1) / w + 1;
float coverageDis = mCoverage / w * distance * childHeight;
t.setAlpha(alpha);
if (mUnselectedScale != 1) {
//居中缩放
final float translateX = childWidth / 2.0f;
final float translateY = childHeight / 2.0f;
mVerticalMatrix.preTranslate(-translateX, -translateY);
mVerticalMatrix.postScale(effectAmount, effectAmount);
mVerticalMatrix.postTranslate(translateX, translateY);
} else {
return true;
}
if (bottomOfCenter) {
float translateY = 0;
translateY = (1 - effectAmount) / 2.0f * childHeight + coverageDis;
float preEffectAmount = 0;
float preCenter = childCenter - childHeight;
preEffectAmount = 1.0f * Math.abs(preCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
while (preCenter > coverFlowCenter && preEffectAmount < 1) {
translateY += (1 - preEffectAmount) * childHeight + mCoverage / w * Math.abs(preCenter - coverFlowCenter) * childHeight;
preCenter -= childHeight;
preEffectAmount = 1.0f * Math.abs(preCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
}
mVerticalMatrix.postTranslate(0, -translateY);
} else {
float translateY = 0;
translateY = (1 - effectAmount) / 2.0f * childHeight + coverageDis;
float nextEffectAmount = 0;
float nextCenter = childCenter + childHeight;
nextEffectAmount = 1.0f * Math.abs(nextCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
while (nextCenter < coverFlowCenter && nextEffectAmount < 1) {
translateY += (1 - nextEffectAmount) * childHeight + mCoverage / w * Math.abs(nextCenter - coverFlowCenter) * childHeight;
nextCenter += childHeight;
nextEffectAmount = 1.0f * Math.abs(nextCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
}
mVerticalMatrix.postTranslate(0, translateY);
}
} else {
final int coverFlowCenter = getHorizontalCenterOfGallery();
final int childWidth = child.getWidth();
final int childHeight = child.getHeight();
final int childCenter = child.getLeft() + childWidth / 2;
float w = childWidth;
boolean rightOfCenter = childCenter - coverFlowCenter >= 0 ? true : false;
t.clear();
mHorizontalMatrix = t.getMatrix();
//线性变化
float distance = Math.abs(childCenter - coverFlowCenter);
float effectAmount = 1.0f * distance * (mUnselectedScale - 1) / w + 1;
float alpha = 1.0f * distance * (getUnselectedAlpha() - 1) / w + 1;
float coverageDis = mCoverage / w * distance * childWidth;
t.setAlpha(alpha);
if (mUnselectedScale != 1) {
//居中缩放
final float translateX = childWidth / 2.0f;
final float translateY = childHeight / 2.0f;
mHorizontalMatrix.preTranslate(-translateX, -translateY);
mHorizontalMatrix.postScale(effectAmount, effectAmount);
mHorizontalMatrix.postTranslate(translateX, translateY);
}
if (rightOfCenter) {
float preEffectAmount = 0;
float preCenter = childCenter - childWidth;
preEffectAmount = 1.0f * Math.abs(preCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
float translateX = 0;
translateX = (1 - effectAmount) / 2.0f * childWidth + coverageDis;
while (preCenter > coverFlowCenter && preEffectAmount < 1) {
translateX += (1 - preEffectAmount) * childWidth + mCoverage / w * Math.abs(preCenter - coverFlowCenter) * childWidth;
preCenter -= childWidth;
preEffectAmount = 1.0f * Math.abs(preCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
}
mHorizontalMatrix.postTranslate(-translateX, 0);
} else {
float nextEffectAmount = 0;
float nextCenter = childCenter + childWidth;
nextEffectAmount = 1.0f * Math.abs(nextCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
float translateX = 0;
translateX = (1 - effectAmount) / 2.0f * childWidth + coverageDis;
while (nextCenter < coverFlowCenter && nextEffectAmount < 1) {
if (DEBUG)
Log.d(TAG, "1nextAmount:" + nextEffectAmount + ",1nextEffectAmount:" + nextEffectAmount);
translateX += (1 - nextEffectAmount) * childWidth + mCoverage / w * Math.abs(nextCenter - coverFlowCenter) * childWidth;
if (DEBUG)
Log.d(TAG, "1translateX:" + translateX);
nextCenter += childWidth;
nextEffectAmount = 1.0f * Math.abs(nextCenter - coverFlowCenter) * (mUnselectedScale - 1) / w + 1;
if (DEBUG)
Log.d(TAG, "2nextAmount:" + nextEffectAmount + ",2nextEffectAmount:" + nextEffectAmount);
}
if (DEBUG)
Log.d(TAG, "translateX:" + translateX);
mHorizontalMatrix.postTranslate(translateX, 0);
}
}
return true;
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
int selectedIndex = getSelectedItemPosition() - getFirstVisiblePosition();
int index = super.getChildDrawingOrder(childCount, i);
Log.d(TAG, "selectedIndex:" + selectedIndex + ",count:" + childCount + ",index:" + i + ",change:" + index);
return index;
}
}