Here are the examples of the java api android.graphics.Camera taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
83 Examples
19
Source : FlipCardAnimation.java
with Apache License 2.0
from zhangke3016
with Apache License 2.0
from zhangke3016
/**
* A 3D Flip Card for Android
*/
public clreplaced FlipCardAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private Camera mCamera;
// 用于确定内容是否开始变化
private boolean isContentChange = false;
private OnContentChangeListener listener;
public FlipCardAnimation(float fromDegrees, float toDegrees, float centerX, float centerY) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
}
// //用于确定内容是否开始变化 在动画开始之前调用
public void setCanContentChange() {
this.isContentChange = false;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (degrees > 90 || degrees < -90) {
if (!isContentChange) {
if (listener != null) {
listener.contentChange();
}
isContentChange = true;
}
if (degrees > 0) {
degrees = 270 + degrees - 90;
} else if (degrees < 0) {
degrees = -270 + (degrees + 90);
}
}
camera.rotateX(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
public void setOnContentChangeListener(OnContentChangeListener listener) {
this.listener = listener;
}
public interface OnContentChangeListener {
void contentChange();
}
}
19
Source : RotateAnimation.java
with Apache License 2.0
from Yuphee
with Apache License 2.0
from Yuphee
/**
* Created by zhangyf on 2015/10/31.
*/
public clreplaced RotateAnimation extends Animation {
/**
* 值为true时可明确查看动画的旋转方向。
*/
public static final boolean DEBUG = false;
/**
* 沿Y轴正方向看,数值减1时动画逆时针旋转。
*/
public static final boolean ROTATE_DECREASE = true;
/**
* 沿Y轴正方向看,数值减1时动画顺时针旋转。
*/
public static final boolean ROTATE_INCREASE = false;
/**
* Z轴上最大深度。
*/
public static final float DEPTH_Z = 310.0f;
/**
* 动画显示时长。
*/
public static final long DURATION = 200l;
/**
* 图片翻转类型。
*/
private final boolean type;
private final float centerX;
private final float centerY;
private Camera camera;
/**
* 用于监听动画进度。当值过半时需更新txtNumber的内容。
*/
private InterpolatedTimeListener listener;
public RotateAnimation(float cX, float cY, boolean type) {
centerX = cX;
centerY = cY;
this.type = type;
setDuration(DURATION);
}
public void initialize(int width, int height, int parentWidth, int parentHeight) {
// 在构造函数之后、getTransformation()之前调用本方法。
super.initialize(width, height, parentWidth, parentHeight);
camera = new Camera();
}
public void setInterpolatedTimeListener(InterpolatedTimeListener listener) {
this.listener = listener;
}
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
// interpolatedTime:动画进度值,范围为[0.0f,1.0f]
if (listener != null) {
listener.interpolatedTime(interpolatedTime);
}
// Log.i("debug",interpolatedTime+"");
float from = 0.0f, to = 0.0f;
if (type == ROTATE_DECREASE) {
from = 0.0f;
// 0~180
to = 180.0f;
} else if (type == ROTATE_INCREASE) {
from = 360.0f;
// 360~180
to = 180.0f;
}
float degree = from + (to - from) * interpolatedTime;
boolean overHalf = (interpolatedTime > 0.5f);
if (overHalf) {
// 翻转过半的情况下,为保证数字仍为可读的文字而非镜面效果的文字,需翻转180度。
degree = degree - 180;
}
// float depth = 0.0f;
float depth = (0.5f - Math.abs(interpolatedTime - 0.5f)) * DEPTH_Z;
final Matrix matrix = transformation.getMatrix();
camera.save();
camera.translate(0.0f, 0.0f, depth);
camera.rotateX(degree);
camera.getMatrix(matrix);
camera.restore();
if (DEBUG) {
if (overHalf) {
matrix.preTranslate(-centerX * 2, -centerY);
matrix.postTranslate(centerX * 2, centerY);
}
} else {
// 确保图片的翻转过程一直处于组件的中心点位置
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
/**
* 动画进度监听器。
*/
public static interface InterpolatedTimeListener {
public void interpolatedTime(float interpolatedTime);
}
}
19
Source : Rotate3dAnimation.java
with Apache License 2.0
from xujiaji
with Apache License 2.0
from xujiaji
public clreplaced Rotate3dAnimation extends Animation {
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
private float mPivotYValue = 0.0f;
private float mFromDegrees;
private float mToDegrees;
private float mPivotX;
private float mPivotY;
private Camera mCamera;
private int mRollType;
public static final int ROLL_BY_X = 0;
public static final int ROLL_BY_Y = 1;
public static final int ROLL_BY_Z = 2;
protected static clreplaced Description {
public int type;
public float value;
}
Description parseValue(TypedValue value) {
Description d = new Description();
if (value == null) {
d.type = ABSOLUTE;
d.value = 0;
} else {
if (value.type == TypedValue.TYPE_FRACTION) {
d.type = (value.data & TypedValue.COMPLEX_UNIT_MASK) == TypedValue.COMPLEX_UNIT_FRACTION_PARENT ? RELATIVE_TO_PARENT : RELATIVE_TO_SELF;
d.value = TypedValue.complexToFloat(value.data);
return d;
} else if (value.type == TypedValue.TYPE_FLOAT) {
d.type = ABSOLUTE;
d.value = value.getFloat();
return d;
} else if (value.type >= TypedValue.TYPE_FIRST_INT && value.type <= TypedValue.TYPE_LAST_INT) {
d.type = ABSOLUTE;
d.value = value.data;
return d;
}
}
d.type = ABSOLUTE;
d.value = 0.0f;
return d;
}
public Rotate3dAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Rotate3dAnimation);
mFromDegrees = a.getFloat(R.styleable.Rotate3dAnimation_fromDeg, 0.0f);
mToDegrees = a.getFloat(R.styleable.Rotate3dAnimation_toDeg, 0.0f);
mRollType = a.getInt(R.styleable.Rotate3dAnimation_rollType, ROLL_BY_X);
Description d = parseValue(a.peekValue(R.styleable.Rotate3dAnimation_pivotX));
mPivotXType = d.type;
mPivotXValue = d.value;
d = parseValue(a.peekValue(R.styleable.Rotate3dAnimation_pivotY));
mPivotYType = d.type;
mPivotYValue = d.value;
a.recycle();
initializePivotPoint();
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees) {
mRollType = rollType;
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotX = 0.0f;
mPivotY = 0.0f;
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees, float pivotX, float pivotY) {
mRollType = rollType;
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
mRollType = rollType;
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
private void initializePivotPoint() {
if (mPivotXType == ABSOLUTE) {
mPivotX = mPivotXValue;
}
if (mPivotYType == ABSOLUTE) {
mPivotY = mPivotYValue;
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final Matrix matrix = t.getMatrix();
mCamera.save();
switch(mRollType) {
case ROLL_BY_X:
mCamera.rotateX(degrees);
break;
case ROLL_BY_Y:
mCamera.rotateY(degrees);
break;
case ROLL_BY_Z:
mCamera.rotateZ(degrees);
break;
}
mCamera.getMatrix(matrix);
mCamera.restore();
matrix.preTranslate(-mPivotX, -mPivotY);
matrix.postTranslate(mPivotX, mPivotY);
}
}
19
Source : PCanvas.java
with GNU General Public License v3.0
from victordiaz
with GNU General Public License v3.0
from victordiaz
public Camera getCamera() {
Camera camera = new Camera();
return camera;
}
19
Source : Rotate3dAnimation.java
with Apache License 2.0
from TutorialsAndroid
with Apache License 2.0
from TutorialsAndroid
public clreplaced Rotate3dAnimation extends Animation {
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
private float mPivotYValue = 0.0f;
private final float fromDegrees, toDegrees;
private float pivotX, pivotY;
private Camera camera;
private final int rollType;
private static final int ROLL_BY_X = 0;
private static final int ROLL_BY_Y = 1;
private static final int ROLL_BY_Z = 2;
static clreplaced Description {
int type;
float value;
}
private Description parseValue(TypedValue value) {
Description d = new Description();
if (value == null) {
d.type = ABSOLUTE;
d.value = 0;
} else {
if (value.type == TypedValue.TYPE_FRACTION) {
d.type = (value.data & TypedValue.COMPLEX_UNIT_MASK) == TypedValue.COMPLEX_UNIT_FRACTION_PARENT ? RELATIVE_TO_PARENT : RELATIVE_TO_SELF;
d.value = TypedValue.complexToFloat(value.data);
return d;
} else if (value.type == TypedValue.TYPE_FLOAT) {
d.type = ABSOLUTE;
d.value = value.getFloat();
return d;
} else if (value.type >= TypedValue.TYPE_FIRST_INT && value.type <= TypedValue.TYPE_LAST_INT) {
d.type = ABSOLUTE;
d.value = value.data;
return d;
}
}
d.type = ABSOLUTE;
d.value = 0.0f;
return d;
}
public Rotate3dAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Rotate3dAnimation);
fromDegrees = a.getFloat(R.styleable.Rotate3dAnimation_fromDeg, 0.0f);
toDegrees = a.getFloat(R.styleable.Rotate3dAnimation_toDeg, 0.0f);
rollType = a.getInt(R.styleable.Rotate3dAnimation_rollType, ROLL_BY_X);
Description d = parseValue(a.peekValue(R.styleable.Rotate3dAnimation_pivotX));
mPivotXType = d.type;
mPivotXValue = d.value;
d = parseValue(a.peekValue(R.styleable.Rotate3dAnimation_pivotY));
mPivotYType = d.type;
mPivotYValue = d.value;
a.recycle();
initializePivotPoint();
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees) {
this.rollType = rollType;
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
pivotX = 0.0f;
pivotY = 0.0f;
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees, float pivotX, float pivotY) {
this.rollType = rollType;
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
this.rollType = rollType;
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
private void initializePivotPoint() {
if (mPivotXType == ABSOLUTE) {
pivotX = mPivotXValue;
}
if (mPivotYType == ABSOLUTE) {
pivotY = mPivotYValue;
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
camera = new Camera();
pivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
pivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = this.fromDegrees;
float degrees = fromDegrees + ((toDegrees - fromDegrees) * interpolatedTime);
final Matrix matrix = t.getMatrix();
camera.save();
switch(rollType) {
case ROLL_BY_X:
camera.rotateX(degrees);
break;
case ROLL_BY_Y:
camera.rotateY(degrees);
break;
case ROLL_BY_Z:
camera.rotateZ(degrees);
break;
}
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);
}
}
19
Source : Rotate3dAnimation.java
with MIT License
from shrikanth7698
with MIT License
from shrikanth7698
public clreplaced Rotate3dAnimation extends Animation {
private final float fromXDegrees;
private final float toXDegrees;
private final float fromYDegrees;
private final float toYDegrees;
private final float fromZDegrees;
private final float toZDegrees;
private Camera camera;
private int width = 0;
private int height = 0;
public Rotate3dAnimation(float fromXDegrees, float toXDegrees, float fromYDegrees, float toYDegrees, float fromZDegrees, float toZDegrees) {
this.fromXDegrees = fromXDegrees;
this.toXDegrees = toXDegrees;
this.fromYDegrees = fromYDegrees;
this.toYDegrees = toYDegrees;
this.fromZDegrees = fromZDegrees;
this.toZDegrees = toZDegrees;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
this.width = width / 4;
this.height = height / 4;
camera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float xDegrees = fromXDegrees + ((toXDegrees - fromXDegrees) * interpolatedTime);
float yDegrees = fromYDegrees + ((toYDegrees - fromYDegrees) * interpolatedTime);
float zDegrees = fromZDegrees + ((toZDegrees - fromZDegrees) * interpolatedTime);
final Matrix matrix = t.getMatrix();
camera.save();
camera.rotateX(xDegrees);
camera.rotateY(yDegrees);
camera.rotateZ(zDegrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-this.width * 2, -this.height / 2);
matrix.postTranslate(this.width * 2, this.height / 2);
}
}
19
Source : InfoGallery.java
with MIT License
from sherry10
with MIT License
from sherry10
/**
* Created by yuxin on 2017/3/15.
*/
public clreplaced InfoGallery extends Gallery {
private Camera mCamera = new Camera();
private int mMaxRotationAngle = 60;
private int mMaxZoom = -60;
private int mCoveflowCenter;
public InfoGallery(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
}
public InfoGallery(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
}
public InfoGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
public int getMaxZoom() {
return mMaxZoom;
}
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
}
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap(child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;
}
transformImageBitmap(child, t, rotationAngle);
}
return true;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
private void transformImageBitmap(View child, Transformation t, int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
final int imageHeight = child.getLayoutParams().height;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);
mCamera.translate(0.0f, 0.0f, 100.0f);
// As the angle of the view gets less, zoom in
if (rotation < mMaxRotationAngle) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
mCamera.restore();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
return true;
} else {
return false;
}
}
}
19
Source : FlipAnimation.java
with Apache License 2.0
from samlss
with Apache License 2.0
from samlss
/**
* @author SamLeung
* @e-mail [email protected]
* @github https://github.com/samlss
* @description Flip-p-p-p animation...
*/
clreplaced FlipAnimation extends Animation {
private float centerX;
private float centerY;
private float fromDegree;
private float toDegree;
private int duration;
private Camera camera = new Camera();
private boolean needToReduce;
private float decayFactor;
private float lastInterpolatedTime = 0;
public FlipAnimation(float fromDegree, float toDegree, float x, float y, int duration, boolean needToReduce) {
this.centerX = x;
this.centerY = y;
this.duration = duration;
this.needToReduce = needToReduce;
this.fromDegree = fromDegree;
this.toDegree = toDegree;
float abs = Math.abs(fromDegree) < Math.abs(toDegree) ? Math.abs(fromDegree) : Math.abs(toDegree);
decayFactor = abs / 3 + 1;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
setDuration(duration);
if (needToReduce) {
setRepeatCount(5);
setRepeatMode(Animation.REVERSE);
}
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float degrees = fromDegree + (toDegree - fromDegree) * interpolatedTime;
Matrix matrix = t.getMatrix();
boolean equals = false;
if (Math.abs(fromDegree) == Math.abs(toDegree))
equals = true;
camera.save();
if ((interpolatedTime != lastInterpolatedTime) && needToReduce) {
if (degrees == toDegree) {
if (fromDegree > 0) {
if (!equals)
fromDegree = -toDegree;
fromDegree -= decayFactor;
if (fromDegree < 0)
fromDegree = 0;
} else {
if (!equals)
fromDegree = -toDegree;
fromDegree += decayFactor;
if (fromDegree > 0)
fromDegree = 0;
}
}
if (degrees == fromDegree) {
if (toDegree > 0) {
toDegree -= decayFactor;
if (toDegree < 0)
toDegree = 0;
} else {
toDegree += decayFactor;
if (toDegree > 0) {
toDegree = 0;
}
}
}
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
lastInterpolatedTime = interpolatedTime;
}
}
19
Source : Rotate3dAnimation.java
with Apache License 2.0
from oktavianto
with Apache License 2.0
from oktavianto
public clreplaced Rotate3dAnimation extends Animation {
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
private float mPivotYValue = 0.0f;
private final float fromDegrees, toDegrees;
private float pivotX, pivotY;
private Camera camera;
private final int rollType;
private static final int ROLL_BY_X = 0;
private static final int ROLL_BY_Y = 1;
private static final int ROLL_BY_Z = 2;
static clreplaced Description {
int type;
float value;
}
private Description parseValue(TypedValue value) {
Description d = new Description();
if (value == null) {
d.type = ABSOLUTE;
d.value = 0;
} else {
if (value.type == TypedValue.TYPE_FRACTION) {
d.type = (value.data & TypedValue.COMPLEX_UNIT_MASK) == TypedValue.COMPLEX_UNIT_FRACTION_PARENT ? RELATIVE_TO_PARENT : RELATIVE_TO_SELF;
d.value = TypedValue.complexToFloat(value.data);
return d;
} else if (value.type == TypedValue.TYPE_FLOAT) {
d.type = ABSOLUTE;
d.value = value.getFloat();
return d;
} else if (value.type >= TypedValue.TYPE_FIRST_INT && value.type <= TypedValue.TYPE_LAST_INT) {
d.type = ABSOLUTE;
d.value = value.data;
return d;
}
}
d.type = ABSOLUTE;
d.value = 0.0f;
return d;
}
public Rotate3dAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Rotate3D);
fromDegrees = a.getFloat(R.styleable.Rotate3D_ion_fromDeg, 0.0f);
toDegrees = a.getFloat(R.styleable.Rotate3D_ion_toDeg, 0.0f);
rollType = a.getInt(R.styleable.Rotate3D_ion_rollType, ROLL_BY_X);
Description d = parseValue(a.peekValue(R.styleable.Rotate3D_ion_pivotX));
mPivotXType = d.type;
mPivotXValue = d.value;
d = parseValue(a.peekValue(R.styleable.Rotate3D_ion_pivotY));
mPivotYType = d.type;
mPivotYValue = d.value;
a.recycle();
initializePivotPoint();
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees) {
this.rollType = rollType;
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
pivotX = 0.0f;
pivotY = 0.0f;
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees, float pivotX, float pivotY) {
this.rollType = rollType;
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
public Rotate3dAnimation(int rollType, float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
this.rollType = rollType;
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
private void initializePivotPoint() {
if (mPivotXType == ABSOLUTE) {
pivotX = mPivotXValue;
}
if (mPivotYType == ABSOLUTE) {
pivotY = mPivotYValue;
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
camera = new Camera();
pivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
pivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = this.fromDegrees;
float degrees = fromDegrees + ((toDegrees - fromDegrees) * interpolatedTime);
final Matrix matrix = t.getMatrix();
camera.save();
switch(rollType) {
case ROLL_BY_X:
camera.rotateX(degrees);
break;
case ROLL_BY_Y:
camera.rotateY(degrees);
break;
case ROLL_BY_Z:
camera.rotateZ(degrees);
break;
}
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);
}
}
19
Source : CourseInfoGallery.java
with Apache License 2.0
from nicolite
with Apache License 2.0
from nicolite
/**
* Created by 高沛 on 2016/7/12.
*/
public clreplaced CourseInfoGallery extends Gallery {
private Camera mCamera = new Camera();
private int mMaxRotationAngle = 60;
private int mMaxZoom = -60;
private int mCoveflowCenter;
public CourseInfoGallery(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
}
public CourseInfoGallery(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
}
public CourseInfoGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
public int getMaxZoom() {
return mMaxZoom;
}
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
}
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap(child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;
}
transformImageBitmap(child, t, rotationAngle);
}
return true;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
private void transformImageBitmap(View child, Transformation t, int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
final int imageHeight = child.getLayoutParams().height;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);
mCamera.translate(0.0f, 0.0f, 100.0f);
// As the angle of the view gets less, zoom in
if (rotation < mMaxRotationAngle) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
mCamera.restore();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
return true;
} else {
return false;
}
}
}
19
Source : Rotate3dAnimation.java
with Apache License 2.0
from kingwang666
with Apache License 2.0
from kingwang666
/**
* Created on 2017/8/24.
* Author: wang
*/
public clreplaced Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation //起始角度
* @param toDegrees the end angle of the 3D rotation //结束角度
* @param centerX the X center of the 3D rotation //x中轴线
* @param centerY the Y center of the 3D rotation //y中轴线
* @param reverse true if the translation should be reversed, false otherwise//是否反转
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
// Z轴移动的距离,这个来影响视觉效果,可以解决flip animation那个给人看似放大的效果
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
19
Source : Rotate3dAnimation.java
with Apache License 2.0
from jiyouliang
with Apache License 2.0
from jiyouliang
/**
* An animation that rotates the view on the Y axis between two specified angles.
* This animation also adds a translation on the Z axis (depth) to improve the effect.
*/
public clreplaced Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
19
Source : Rotate3dAnimation.java
with MIT License
from JingYeoh
with MIT License
from JingYeoh
/**
* An animation that rotates the view on the Y axis between two specified angles.
* This animation also adds a translation on the Z axis (depth) to improve the effect.
* <p>
* <a href="https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.java">Rotate3dAnimation</a>
*/
public clreplaced Rotate3dAnimation extends Animation {
private static final int TYPE_SCALE = 0;
private static final int TYPE_PX = 1;
private final float mFromDegrees;
private final float mToDegrees;
private float mCenterX;
private float mCenterY;
private float mDepthZ;
private int mType = TYPE_PX;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse, int type) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
mType = type;
}
public Rotate3dAnimation(float fromDegrees, float toDegrees, boolean reverse) {
this(fromDegrees, toDegrees, 0.5f, 0.5f, 0.5f, reverse, TYPE_SCALE);
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
if (mType == TYPE_SCALE) {
mCenterX = width * mCenterX;
mCenterY = height * mCenterY;
mDepthZ = width * mDepthZ;
}
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
19
Source : Rotate3dAnimation.java
with Apache License 2.0
from JasonFengIce
with Apache License 2.0
from JasonFengIce
/**
* 一个在指定了两个角度的在Y轴旋转的动画类.
* 这个类也添加了一个z轴的属性用来提高效果.
* An animation that rotates the view on the Y axis between two specified angles.
* This animation also adds a translation on the Z axis (depth) to improve the effect.
*/
public clreplaced Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* 在Y轴创建了一个新的3D的旋转动画,这个旋转动画定义了它的开始角度和结束角度,
* 两个角度的单位都是度数,这个旋转动画围绕在2D空间的中心点执行.
* 你可以用X轴坐标(叫做centerX)和Y轴(叫做centerY)坐标来定义这个中心点.
* 当动画开始时,对于z轴(深度)的转换就会被执行.转换的长度和转换正向反向都可以指定.
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation 开始的角度
* @param toDegrees the end angle of the 3D rotation 结束的角度
* @param centerX the X center of the 3D rotation 中心点X轴坐标
* @param centerY the Y center of the 3D rotation 中心点Y轴坐标
* @param reverse true if the translation should be reversed, false otherwise true表示反向,false表示正向
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
19
Source : Rotate3DAnimation.java
with Apache License 2.0
from InnoFang
with Apache License 2.0
from InnoFang
/**
* Author: Inno Fang
* Time: 2017/4/15 15:26
* Description:
*/
public clreplaced Rotate3DAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
// <------- 像素密度
float scale = 1;
public Rotate3DAnimation(Context context, float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
// 获取手机像素密度 (即dp与px的比例)
scale = context.getResources().getDisplayMetrics().density;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
// 调节深度
if (mReverse)
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
else
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
// 绕y轴旋转
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
// 修正失真,主要修改 MPERSP_0 和 MPERSP_1
float[] mValues = new float[9];
// 获取数值
matrix.getValues(mValues);
// 数值修正
mValues[6] = mValues[6] / scale;
// 数值修正
mValues[7] = mValues[7] / scale;
// 重新赋值
matrix.setValues(mValues);
// 调节中心点
matrix.preTranslate(-centerX, -centerY);
matrix.postScale(centerX, centerY);
}
}
19
Source : FancyCoverFlow.java
with Apache License 2.0
from iamvaliyev
with Apache License 2.0
from iamvaliyev
public clreplaced FancyCoverFlow extends Gallery {
// =============================================================================
// Constants
// =============================================================================
public static final int ACTION_DISTANCE_AUTO = Integer.MAX_VALUE;
public static final float SCALEDOWN_GRAVITY_TOP = 0.0f;
public static final float SCALEDOWN_GRAVITY_CENTER = 0.5f;
public static final float SCALEDOWN_GRAVITY_BOTTOM = 1.0f;
// =============================================================================
// Private members
// =============================================================================
private float reflectionRatio = 0.4f;
private int reflectionGap = 20;
private boolean reflectionEnabled = false;
/**
* TODO: Doc
*/
private float unselectedAlpha;
/**
* Camera used for view transformation.
*/
private Camera transformationCamera;
/**
* TODO: Doc
*/
private int maxRotation = 75;
/**
* Factor (0-1) that defines how much the unselected children should be scaled down. 1 means no scaledown.
*/
private float unselectedScale;
/**
* TODO: Doc
*/
private float scaleDownGravity = SCALEDOWN_GRAVITY_CENTER;
/**
* Distance in pixels between the transformation effects (alpha, rotation, zoom) are applied.
*/
private int actionDistance;
/**
* Saturation factor (0-1) of items that reach the outer effects distance.
*/
private float unselectedSaturation;
// =============================================================================
// Constructors
// =============================================================================
public FancyCoverFlow(Context context) {
super(context);
this.initialize();
}
public FancyCoverFlow(Context context, AttributeSet attrs) {
super(context, attrs);
this.initialize();
this.applyXmlAttributes(attrs);
}
public FancyCoverFlow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.initialize();
this.applyXmlAttributes(attrs);
}
private void initialize() {
this.transformationCamera = new Camera();
this.setSpacing(0);
}
private void applyXmlAttributes(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FancyCoverFlow);
this.actionDistance = a.getInteger(R.styleable.FancyCoverFlow_actionDistance, ACTION_DISTANCE_AUTO);
this.scaleDownGravity = a.getFloat(R.styleable.FancyCoverFlow_scaleDownGravity, 1.0f);
this.maxRotation = a.getInteger(R.styleable.FancyCoverFlow_maxRotation, 45);
this.unselectedAlpha = a.getFloat(R.styleable.FancyCoverFlow_unselectedAlpha, 0.3f);
this.unselectedSaturation = a.getFloat(R.styleable.FancyCoverFlow_unselectedSaturation, 0.0f);
this.unselectedScale = a.getFloat(R.styleable.FancyCoverFlow_unselectedScale, 0.75f);
}
// =============================================================================
// Getter / Setter
// =============================================================================
public float getReflectionRatio() {
return reflectionRatio;
}
public void setReflectionRatio(float reflectionRatio) {
if (reflectionRatio <= 0 || reflectionRatio > 0.5f) {
throw new IllegalArgumentException("reflectionRatio may only be in the interval (0, 0.5]");
}
this.reflectionRatio = reflectionRatio;
if (this.getAdapter() != null) {
((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();
}
}
public int getReflectionGap() {
return reflectionGap;
}
public void setReflectionGap(int reflectionGap) {
this.reflectionGap = reflectionGap;
if (this.getAdapter() != null) {
((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();
}
}
public boolean isReflectionEnabled() {
return reflectionEnabled;
}
public void setReflectionEnabled(boolean reflectionEnabled) {
this.reflectionEnabled = reflectionEnabled;
if (this.getAdapter() != null) {
((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();
}
}
/**
* Use this to provide a {@link FancyCoverFlowAdapter} to the coverflow. This
* method will throw an {@link ClreplacedCastException} if the preplaceded adapter does not
* subclreplaced {@link FancyCoverFlowAdapter}.
*
* @param adapter
*/
@Override
public void setAdapter(SpinnerAdapter adapter) {
if (!(adapter instanceof FancyCoverFlowAdapter)) {
throw new ClreplacedCastException(FancyCoverFlow.clreplaced.getSimpleName() + " only works in conjunction with a " + FancyCoverFlowAdapter.clreplaced.getSimpleName());
}
super.setAdapter(adapter);
}
/**
* Returns the maximum rotation that is applied to items left and right of the center of the coverflow.
*
* @return
*/
public int getMaxRotation() {
return maxRotation;
}
/**
* Sets the maximum rotation that is applied to items left and right of the center of the coverflow.
*
* @param maxRotation
*/
public void setMaxRotation(int maxRotation) {
this.maxRotation = maxRotation;
}
/**
* TODO: Write doc
*
* @return
*/
public float getUnselectedAlpha() {
return this.unselectedAlpha;
}
/**
* TODO: Write doc
*
* @return
*/
public float getUnselectedScale() {
return unselectedScale;
}
/**
* TODO: Write doc
*
* @param unselectedScale
*/
public void setUnselectedScale(float unselectedScale) {
this.unselectedScale = unselectedScale;
}
/**
* TODO: Doc
*
* @return
*/
public float getScaleDownGravity() {
return scaleDownGravity;
}
/**
* TODO: Doc
*
* @param scaleDownGravity
*/
public void setScaleDownGravity(float scaleDownGravity) {
this.scaleDownGravity = scaleDownGravity;
}
/**
* TODO: Write doc
*
* @return
*/
public int getActionDistance() {
return actionDistance;
}
/**
* TODO: Write doc
*
* @param actionDistance
*/
public void setActionDistance(int actionDistance) {
this.actionDistance = actionDistance;
}
/**
* TODO: Write doc
*
* @param unselectedAlpha
*/
@Override
public void setUnselectedAlpha(float unselectedAlpha) {
super.setUnselectedAlpha(unselectedAlpha);
this.unselectedAlpha = unselectedAlpha;
}
/**
* TODO: Write doc
*
* @return
*/
public float getUnselectedSaturation() {
return unselectedSaturation;
}
/**
* TODO: Write doc
*
* @param unselectedSaturation
*/
public void setUnselectedSaturation(float unselectedSaturation) {
this.unselectedSaturation = unselectedSaturation;
}
// =============================================================================
// Supertype overrides
// =============================================================================
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
// We can cast here because FancyCoverFlowAdapter only creates wrappers.
FancyCoverFlowItemWrapper item = (FancyCoverFlowItemWrapper) child;
// Since Jelly Bean childs won't get invalidated automatically, needs to be added for the smooth coverflow animation
if (android.os.Build.VERSION.SDK_INT >= 16) {
item.invalidate();
}
final int coverFlowWidth = this.getWidth();
final int coverFlowCenter = coverFlowWidth / 2;
final int childWidth = item.getWidth();
final int childHeight = item.getHeight();
final int childCenter = item.getLeft() + childWidth / 2;
// Use coverflow width when its defined as automatic.
final int actionDistance = (this.actionDistance == ACTION_DISTANCE_AUTO) ? (int) ((coverFlowWidth + childWidth) / 2.0f) : this.actionDistance;
// Calculate the abstract amount for all effects.
final float effectsAmount = Math.min(1.0f, Math.max(-1.0f, (1.0f / actionDistance) * (childCenter - coverFlowCenter)));
// Clear previous transformations and set transformation type (matrix + alpha).
t.clear();
t.setTransformationType(Transformation.TYPE_BOTH);
// Alpha
if (this.unselectedAlpha != 1) {
final float alphaAmount = (this.unselectedAlpha - 1) * Math.abs(effectsAmount) + 1;
t.setAlpha(alphaAmount);
}
// Saturation
if (this.unselectedSaturation != 1) {
// Preplaced over saturation to the wrapper.
final float saturationAmount = (this.unselectedSaturation - 1) * Math.abs(effectsAmount) + 1;
item.setSaturation(saturationAmount);
}
final Matrix imageMatrix = t.getMatrix();
// Apply rotation.
if (this.maxRotation != 0) {
final int rotationAngle = (int) (-effectsAmount * this.maxRotation);
this.transformationCamera.save();
this.transformationCamera.rotateY(rotationAngle);
this.transformationCamera.getMatrix(imageMatrix);
this.transformationCamera.restore();
}
// Zoom.
if (this.unselectedScale != 1) {
final float zoomAmount = (this.unselectedScale - 1) * Math.abs(effectsAmount) + 1;
// Calculate the scale anchor (y anchor can be altered)
final float translateX = childWidth / 2.0f;
final float translateY = childHeight * this.scaleDownGravity;
imageMatrix.preTranslate(-translateX, -translateY);
imageMatrix.postScale(zoomAmount, zoomAmount);
imageMatrix.postTranslate(translateX, translateY);
}
return true;
}
// =============================================================================
// Public clreplacedes
// =============================================================================
public static clreplaced LayoutParams extends Gallery.LayoutParams {
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(int w, int h) {
super(w, h);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
}
19
Source : FlipAnimation.java
with MIT License
from ABTSoftware
with MIT License
from ABTSoftware
public clreplaced FlipAnimation extends Animation {
private final float fromDegrees;
private final float toDegrees;
private final float centerX;
private final float centerY;
private Camera mCamera;
public FlipAnimation(float fromDegrees, float toDegrees, float centerX, float centerY) {
this.fromDegrees = fromDegrees;
this.toDegrees = toDegrees;
this.centerX = centerX;
this.centerY = centerY;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float degrees = fromDegrees + ((toDegrees - fromDegrees) * interpolatedTime);
final Matrix matrix = t.getMatrix();
final Camera camera = mCamera;
camera.save();
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
18
Source : TabletTransformer.java
with Apache License 2.0
from wenchaosong
with Apache License 2.0
from wenchaosong
public clreplaced TabletTransformer extends ABaseTransformer {
private static final Matrix OFFSET_MATRIX = new Matrix();
private static final Camera OFFSET_CAMERA = new Camera();
private static final float[] OFFSET_TEMP_FLOAT = new float[2];
@Override
protected void onTransform(View view, float position) {
final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
view.setTranslationX(getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
view.setPivotX(view.getWidth() * 0.5f);
view.setPivotY(0);
view.setRotationY(rotation);
}
protected static final float getOffsetXForRotation(float degrees, int width, int height) {
OFFSET_MATRIX.reset();
OFFSET_CAMERA.save();
OFFSET_CAMERA.rotateY(Math.abs(degrees));
OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
OFFSET_CAMERA.restore();
OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
OFFSET_TEMP_FLOAT[0] = width;
OFFSET_TEMP_FLOAT[1] = height;
OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
}
18
Source : FlipAnimation.java
with MIT License
from riteshakya037
with MIT License
from riteshakya037
/**
* Flip animation for cards view. Switching between to view while changing camera.
* <p>
* Created by Ritesh Shakya on 8/24/2016.
*/
public clreplaced FlipAnimation extends Animation {
/**
* Change the camera of view while animating.
*/
private Camera camera;
/**
* Current active view
*/
private View fromView;
/**
* View to rotate to.
*/
private View toView;
/**
* Center X value of view
*/
private float centerX;
/**
* Center Y value of view.
*/
private float centerY;
private boolean forward = true;
public FlipAnimation(View fromView, View toView) {
this.fromView = fromView;
this.toView = toView;
setDuration(700);
setFillAfter(false);
setInterpolator(new AccelerateDecelerateInterpolator());
}
/**
* Play animation in reverse.
*/
public void reverse() {
forward = false;
View switchView = toView;
toView = fromView;
fromView = switchView;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
centerX = width / 2;
centerY = height / 2;
camera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final double radians = Math.PI * interpolatedTime;
float degrees = (float) (180.0 * radians / Math.PI);
if (interpolatedTime >= 0.5f) {
// Alternate the visibility of views at the exact half of animation duration.
degrees -= 180.f;
fromView.setVisibility(View.GONE);
toView.setVisibility(View.VISIBLE);
}
if (forward)
degrees = -degrees;
final Matrix matrix = t.getMatrix();
camera.save();
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
18
Source : CameraSubject.java
with Apache License 2.0
from pkware
with Apache License 2.0
from pkware
/**
* Propositions for {@link Camera} subjects.
*/
public clreplaced CameraSubject extends Subject {
@Nullable
private final Camera actual;
public CameraSubject(@Nonnull FailureMetadata failureMetadata, @Nullable Camera actual) {
super(failureMetadata, actual);
this.actual = actual;
}
@TargetApi(JELLY_BEAN)
public void hasLocationX(float location, float tolerance) {
check("getLocationX()").that(actual.getLocationX()).isWithin(tolerance).of(location);
}
@TargetApi(JELLY_BEAN)
public void hasLocationY(float location, float tolerance) {
check("getLocationY()").that(actual.getLocationY()).isWithin(tolerance).of(location);
}
@TargetApi(JELLY_BEAN)
public void hasLocationZ(float location, float tolerance) {
check("getLocationZ()").that(actual.getLocationZ()).isWithin(tolerance).of(location);
}
}
18
Source : TabletTransformer.java
with MIT License
from Omega-R
with MIT License
from Omega-R
public clreplaced TabletTransformer implements ItemTransformer {
private final Matrix mOffsetMatrix = new Matrix();
private final Camera mOffsetCamera = new Camera();
private final float[] mOffset = new float[2];
@Override
public void transformItem(View view, float position, boolean isHorizontal, int scrolled) {
float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
int width = view.getWidth();
int height = view.getHeight();
if (isHorizontal) {
view.setTranslationX(getOffsetForRotation(rotation, width, height, true));
view.setPivotX(width * 0.5f);
view.setPivotY(0);
view.setRotationY(rotation);
} else {
view.setTranslationY(getOffsetForRotation(rotation, width, height, false));
view.setPivotY(height * 0.5f);
view.setPivotX(0);
view.setRotationX(-rotation);
}
}
private float getOffsetForRotation(float degrees, int width, int height, boolean isHorizontal) {
mOffsetMatrix.reset();
mOffsetCamera.save();
if (isHorizontal) {
mOffsetCamera.rotateY(Math.abs(degrees));
} else {
mOffsetCamera.rotateX(Math.abs(degrees));
}
mOffsetCamera.getMatrix(mOffsetMatrix);
mOffsetCamera.restore();
mOffsetMatrix.preTranslate(-width * 0.5f, -height * 0.5f);
mOffsetMatrix.postTranslate(width * 0.5f, height * 0.5f);
mOffset[0] = width;
mOffset[1] = height;
mOffsetMatrix.mapPoints(mOffset);
if (isHorizontal) {
return (width - mOffset[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
} else {
return (height - mOffset[1]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
}
}
18
Source : TabletTransformer.java
with Apache License 2.0
from myinnos
with Apache License 2.0
from myinnos
public clreplaced TabletTransformer extends BaseTransformer {
private static final Matrix OFFSET_MATRIX = new Matrix();
private static final Camera OFFSET_CAMERA = new Camera();
private static final float[] OFFSET_TEMP_FLOAT = new float[2];
@Override
protected void onTransform(View view, float position) {
final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
ViewHelper.setTranslationX(view, getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
ViewHelper.setPivotX(view, view.getWidth() * 0.5f);
ViewHelper.setPivotY(view, 0);
ViewHelper.setRotationY(view, rotation);
}
protected static final float getOffsetXForRotation(float degrees, int width, int height) {
OFFSET_MATRIX.reset();
OFFSET_CAMERA.save();
OFFSET_CAMERA.rotateY(Math.abs(degrees));
OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
OFFSET_CAMERA.restore();
OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
OFFSET_TEMP_FLOAT[0] = width;
OFFSET_TEMP_FLOAT[1] = height;
OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
}
18
Source : TriangleSkewSpinIndicator.java
with Apache License 2.0
from madreain
with Apache License 2.0
from madreain
/**
* Created by Jack on 2015/10/20.
*/
public clreplaced TriangleSkewSpinIndicator extends Indicator {
private float rotateX;
private float rotateY;
private Camera mCamera;
private Matrix mMatrix;
public TriangleSkewSpinIndicator() {
mCamera = new Camera();
mMatrix = new Matrix();
}
@Override
public void draw(Canvas canvas, Paint paint) {
mMatrix.reset();
mCamera.save();
mCamera.rotateX(rotateX);
mCamera.rotateY(rotateY);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-centerX(), -centerY());
mMatrix.postTranslate(centerX(), centerY());
canvas.concat(mMatrix);
Path path = new Path();
path.moveTo(getWidth() / 5, getHeight() * 4 / 5);
path.lineTo(getWidth() * 4 / 5, getHeight() * 4 / 5);
path.lineTo(getWidth() / 2, getHeight() / 5);
path.close();
canvas.drawPath(path, paint);
}
@Override
public ArrayList<ValueAnimator> onCreateAnimators() {
ArrayList<ValueAnimator> animators = new ArrayList<>();
ValueAnimator animator = ValueAnimator.ofFloat(0, 180, 180, 0, 0);
addUpdateListener(animator, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rotateX = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(-1);
animator.setDuration(2500);
ValueAnimator animator1 = ValueAnimator.ofFloat(0, 0, 180, 180, 0);
addUpdateListener(animator1, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rotateY = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator1.setInterpolator(new LinearInterpolator());
animator1.setRepeatCount(-1);
animator1.setDuration(2500);
animators.add(animator);
animators.add(animator1);
return animators;
}
}
18
Source : SquareSpinIndicator.java
with Apache License 2.0
from madreain
with Apache License 2.0
from madreain
/**
* Created by Jack on 2015/10/16.
*/
public clreplaced SquareSpinIndicator extends Indicator {
private float rotateX;
private float rotateY;
private Camera mCamera;
private Matrix mMatrix;
public SquareSpinIndicator() {
mCamera = new Camera();
mMatrix = new Matrix();
}
@Override
public void draw(Canvas canvas, Paint paint) {
mMatrix.reset();
mCamera.save();
mCamera.rotateX(rotateX);
mCamera.rotateY(rotateY);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-centerX(), -centerY());
mMatrix.postTranslate(centerX(), centerY());
canvas.concat(mMatrix);
canvas.drawRect(new RectF(getWidth() / 5, getHeight() / 5, getWidth() * 4 / 5, getHeight() * 4 / 5), paint);
}
@Override
public ArrayList<ValueAnimator> onCreateAnimators() {
ArrayList<ValueAnimator> animators = new ArrayList<>();
ValueAnimator animator = ValueAnimator.ofFloat(0, 180, 180, 0, 0);
addUpdateListener(animator, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rotateX = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(-1);
animator.setDuration(2500);
ValueAnimator animator1 = ValueAnimator.ofFloat(0, 0, 180, 180, 0);
addUpdateListener(animator1, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rotateY = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator1.setInterpolator(new LinearInterpolator());
animator1.setRepeatCount(-1);
animator1.setDuration(2500);
animators.add(animator);
animators.add(animator1);
return animators;
}
}
18
Source : BallPulseRiseIndicator.java
with Apache License 2.0
from madreain
with Apache License 2.0
from madreain
/**
* Created by Jack on 2015/10/17.
*/
public clreplaced BallPulseRiseIndicator extends Indicator {
private Camera mCamera;
private Matrix mMatrix;
private float degress;
public BallPulseRiseIndicator() {
mCamera = new Camera();
mMatrix = new Matrix();
}
@Override
public void draw(Canvas canvas, Paint paint) {
mMatrix.reset();
mCamera.save();
mCamera.rotateX(degress);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-centerX(), -centerY());
mMatrix.postTranslate(centerX(), centerY());
canvas.concat(mMatrix);
float radius = getWidth() / 10;
canvas.drawCircle(getWidth() / 4, radius * 2, radius, paint);
canvas.drawCircle(getWidth() * 3 / 4, radius * 2, radius, paint);
canvas.drawCircle(radius, getHeight() - 2 * radius, radius, paint);
canvas.drawCircle(getWidth() / 2, getHeight() - 2 * radius, radius, paint);
canvas.drawCircle(getWidth() - radius, getHeight() - 2 * radius, radius, paint);
}
@Override
public ArrayList<ValueAnimator> onCreateAnimators() {
ArrayList<ValueAnimator> animators = new ArrayList<>();
ValueAnimator animator = ValueAnimator.ofFloat(0, 360);
addUpdateListener(animator, new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
degress = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(-1);
animator.setDuration(1500);
animators.add(animator);
return animators;
}
}
18
Source : TextView3D.java
with Apache License 2.0
from JustinRoom
with Apache License 2.0
from JustinRoom
/**
* <br>Email:[email protected]
* <br>QQ:1006368252
* <br><a href="https://github.com/JustinRoom/WheelViewDemo" target="_blank">https://github.com/JustinRoom/WheelViewDemo</a>
*
* @author jiangshicheng
*/
public clreplaced TextView3D extends android.support.v7.widget.AppCompatTextView {
Matrix matrix = new Matrix();
Camera camera = new Camera();
float angle;
public TextView3D(Context context) {
this(context, null);
}
public TextView3D(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public TextView3D(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextView3D, defStyleAttr, 0);
angle = a.getFloat(R.styleable.TextView3D_angle, 0);
a.recycle();
setGravity(Gravity.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
float cx = getWidth() / 2.0f;
float cy = getHeight() / 2.0f;
matrix.reset();
camera.save();
camera.rotateX(angle);
camera.getMatrix(matrix);
camera.restore();
matrix.postTranslate(cx, cy);
matrix.preTranslate(-cx, -cy);
canvas.concat(matrix);
super.onDraw(canvas);
}
}
18
Source : TabletTransformer.java
with MIT License
from HamidrezaAmz
with MIT License
from HamidrezaAmz
public clreplaced TabletTransformer extends BaseTransformer {
private static final Matrix OFFSET_MATRIX = new Matrix();
private static final Camera OFFSET_CAMERA = new Camera();
private static final float[] OFFSET_TEMP_FLOAT = new float[2];
@Override
protected void onTransform(View view, float position) {
final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
view.setTranslationX(getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
view.setPivotX(view.getWidth() * 0.5f);
view.setPivotY(0);
view.setRotationY(rotation);
}
protected static final float getOffsetXForRotation(float degrees, int width, int height) {
OFFSET_MATRIX.reset();
OFFSET_CAMERA.save();
OFFSET_CAMERA.rotateY(Math.abs(degrees));
OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
OFFSET_CAMERA.restore();
OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
OFFSET_TEMP_FLOAT[0] = width;
OFFSET_TEMP_FLOAT[1] = height;
OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
}
18
Source : TableTransformer.java
with Artistic License 2.0
from gdutxiaoxu
with Artistic License 2.0
from gdutxiaoxu
/**
* @ explain:
* @ author:xujun on 2016/8/15 10:45
* @ email:[email protected]
*/
public clreplaced TableTransformer extends BaseTransformer {
private static final Matrix OFFSET_MATRIX = new Matrix();
private static final Camera OFFSET_CAMERA = new Camera();
private static final float[] OFFSET_TEMP_FLOAT = new float[2];
private static final float minScale = 0.6f;
@Override
protected void onTransform(View view, float position) {
final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
view.setTranslationX(getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
view.setPivotX(view.getWidth() * 0.5f);
view.setPivotY(0);
view.setRotationY(rotation);
float scaleX = Math.max(1 - Math.abs(position), minScale);
view.setScaleX(scaleX);
}
protected static final float getOffsetXForRotation(float degrees, int width, int height) {
OFFSET_MATRIX.reset();
OFFSET_CAMERA.save();
OFFSET_CAMERA.rotateY(Math.abs(degrees));
OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
OFFSET_CAMERA.restore();
OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
OFFSET_TEMP_FLOAT[0] = width;
OFFSET_TEMP_FLOAT[1] = height;
OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
}
18
Source : TabletTransformer.java
with Apache License 2.0
from ckrgithub
with Apache License 2.0
from ckrgithub
public clreplaced TabletTransformer extends BaseTransformer {
private static final Matrix OFFSET_MATRIX = new Matrix();
private static final Camera OFFSET_CAMERA = new Camera();
private static final float[] OFFSET_TEMP_FLOAT = new float[2];
@Override
protected void onTransform(View view, float position, boolean forwardDirection, int mOrientation) {
final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
if (mOrientation == OnPageDataListener.HORIZONTAL) {
view.setTranslationX(getOffsetForRotation(rotation, view.getWidth(), view.getHeight(), mOrientation));
view.setPivotX(view.getWidth() * 0.5f);
view.setPivotY(0);
view.setRotationY(rotation);
} else {
view.setTranslationY(getOffsetForRotation(rotation, view.getWidth(), view.getHeight(), mOrientation));
view.setPivotY(view.getHeight() * 0.5f);
view.setPivotX(0);
view.setRotationX(-rotation);
}
}
protected static final float getOffsetForRotation(float degrees, int width, int height, int mOrientation) {
OFFSET_MATRIX.reset();
OFFSET_CAMERA.save();
if (mOrientation == OnPageDataListener.HORIZONTAL) {
OFFSET_CAMERA.rotateY(Math.abs(degrees));
} else {
OFFSET_CAMERA.rotateX(-Math.abs(degrees));
}
OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
OFFSET_CAMERA.restore();
OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
OFFSET_TEMP_FLOAT[0] = width;
OFFSET_TEMP_FLOAT[1] = height;
OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
if (mOrientation == OnPageDataListener.HORIZONTAL) {
return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
} else {
return (height - OFFSET_TEMP_FLOAT[1]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
}
}
18
Source : Rotate3dAnimation.java
with Apache License 2.0
from akhasoft
with Apache License 2.0
from akhasoft
/**
* An animation that rotates the view on the Y axis between two specified angles.
* This animation also adds a translation on the Z axis (depth) to improve the effect.
*/
@SuppressWarnings("WeakerAccess")
public clreplaced Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, defined by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, @SuppressWarnings("SameParameterValue") float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
17
Source : FlipCard.java
with Apache License 2.0
from yiyuanliu
with Apache License 2.0
from yiyuanliu
/**
* Created by YiyuanLiu on 2016/12/15.
*/
public clreplaced FlipCard extends FrameLayout {
private static final String TAG = "FlipCard";
private Paint mScrimPaint;
private Camera mCamera;
private Matrix mMatrix;
private boolean mIsForground;
private float mPercent;
public FlipCard(Context context) {
this(context, null);
}
public FlipCard(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlipCard(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScrimPaint = new Paint();
mCamera = new Camera();
mMatrix = new Matrix();
}
public void setState(boolean isForground, float percent) {
mIsForground = isForground;
mPercent = percent;
}
@Override
public void draw(Canvas canvas) {
if (mPercent == 0) {
super.draw(canvas);
return;
}
final int height = canvas.getHeight();
final int width = canvas.getWidth();
final float percent = mPercent > 0 ? mPercent : -mPercent;
if (mIsForground) {
// clip card effect for forground view
// draw part1
int save1 = canvas.save();
if (mPercent > 0) {
canvas.clipRect(0, 0, width, height / 2);
} else {
canvas.clipRect(0, height / 2, width, height);
}
super.draw(canvas);
canvas.restoreToCount(save1);
// draw part2
if (mPercent < 0) {
canvas.clipRect(0, 0, width, height / 2);
} else {
canvas.clipRect(0, height / 2, width, height);
}
mCamera.save();
mCamera.setLocation(0f, 0f, -80);
mCamera.rotateX(mPercent * 180);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-width / 2, -height / 2);
mMatrix.postTranslate(width / 2, height / 2);
canvas.concat(mMatrix);
super.draw(canvas);
mScrimPaint.setColor(0x08000000);
canvas.drawRect(0, 0, width, height, mScrimPaint);
} else {
// draw shadow for underground view
final int scrimColor = (int) (0xff * (1 - percent * 2)) << 24;
mScrimPaint.setColor(scrimColor);
if (mPercent < 0) {
canvas.clipRect(0, 0, width, height / 2);
} else {
canvas.clipRect(0, height / 2, width, height);
}
super.draw(canvas);
canvas.drawRect(0, 0, width, height, mScrimPaint);
}
}
}
17
Source : SphereLayout.java
with MIT License
from thunderpunch
with MIT License
from thunderpunch
/**
* Created by thunderpunch on 2017/2/20
*/
public clreplaced SphereLayout extends ViewGroup {
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
private int mRadius;
private Point mCenter;
private Camera mCamera;
private Matrix mMatrix;
private float mDensity;
private int mRotateDegree;
private int mDirection;
private float[] mValues = new float[9];
private boolean mReverse;
private boolean mHideBack;
private ArrayList<View> mPositiveChildren, mNegativeChildren;
private int mOrientation;
private OnRotateListener mRotateListener;
/**
* @see #rotateDependsOn(SphereLayout)
*/
private SphereLayout mDependency;
/**
* 自身翻转中心到依赖视图的翻转中心的偏移量
*
* @see #rotateDependsOn(SphereLayout)
*/
private int[] mDependencyOffset;
private boolean mCheckedDependencyOffset;
public SphereLayout(Context context) {
this(context, null);
}
public SphereLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SphereLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SphereLayout);
// 球体半径
mRadius = a.getDimensionPixelSize(R.styleable.SphereLayout_radius, 0);
// 标记位于背面的视图是以Y轴水平翻转到达正面 或是以X轴竖直翻转可到达正面
mOrientation = a.getInt(R.styleable.SphereLayout_snapOrientation, HORIZONTAL);
// 是否隐藏处在背面的布局
mHideBack = a.getBoolean(R.styleable.SphereLayout_hideBack, false);
a.recycle();
mCenter = new Point();
mCamera = new Camera();
mDependencyOffset = new int[2];
// mCamera.setLocation(0, 0, -20);
mMatrix = new Matrix();
// depth为正的childview集合
mPositiveChildren = new ArrayList<>();
// depth为负的childview集合
mNegativeChildren = new ArrayList<>();
mDensity = getResources().getDisplayMetrics().density;
}
/**
* @param hideBack 是否隐藏背面
*/
public void hideBack(boolean hideBack) {
if (mHideBack != hideBack) {
mHideBack = hideBack;
postInvalidate();
}
}
/**
* @param radius 球体半径
*/
public void setRadius(int radius) {
mRadius = radius;
requestLayout();
}
public int getRadius() {
return mRadius;
}
/**
* @param isReverse 是否翻转
*/
public void reverse(boolean isReverse) {
if (isReverse != mReverse) {
mReverse = isReverse;
mRotateDegree = 0;
invalidate();
}
}
public boolean isReverse() {
return mReverse;
}
public int getCenterX() {
return mCenter.x;
}
public int getCenterY() {
return mCenter.y;
}
/**
* @param direction 翻转方向 (-180,180] 以布局中心为原点,向量与x轴正方向的夹角,顺加逆减
* @param rotateDegree 翻转角度 (-180,180]
*/
public void rotate(int direction, int rotateDegree) {
mDirection = makeDirectionWithinRange(direction);
mRotateDegree = makeRoatateDegreeWithinRange(rotateDegree);
postInvalidate();
if (mRotateListener != null) {
mRotateListener.onRotate(direction, rotateDegree);
}
}
/**
* @param sphereLayout 翻转依赖
*/
public void rotateDependsOn(SphereLayout sphereLayout) {
mDependency = sphereLayout;
mCheckedDependencyOffset = false;
mDependency.mRotateListener = new OnRotateListener() {
@Override
public void onRotate(int direction, int degree) {
rotate(direction, degree);
}
};
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mRadius == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(mRadius << 1, MeasureSpec.EXACTLY);
}
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mRadius << 1, MeasureSpec.EXACTLY);
}
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.fitBounds) {
lp.depth = Math.max(Math.min(lp.depth, mRadius), -mRadius);
lp.bottomMargin = lp.leftMargin = lp.rightMargin = lp.topMargin = 0;
final int boundsSize = (int) Math.max(getMinimumBoundsSize(), 2 * Math.sqrt(mRadius * mRadius - lp.depth * lp.depth));
child.measure(MeasureSpec.makeMeasureSpec(boundsSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(boundsSize, MeasureSpec.EXACTLY));
} else {
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
}
}
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mCenter.x = w >> 1;
mCenter.y = h >> 1;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mPositiveChildren.clear();
mNegativeChildren.clear();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
int childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin;
int childTop = (b - t - height) / 2 + lp.topMargin - lp.bottomMargin;
child.layout(childLeft, childTop, childLeft + width, childTop + height);
if (lp.depth >= 0) {
mPositiveChildren.add(child);
} else {
mNegativeChildren.add(child);
}
}
}
final Comparator<View> comparator = new Comparator<View>() {
@Override
public int compare(View o1, View o2) {
Integer d0 = Math.abs(((LayoutParams) o1.getLayoutParams()).depth);
Integer d1 = Math.abs(((LayoutParams) o2.getLayoutParams()).depth);
return d0.compareTo(d1);
}
};
// 按照depth绝对值排列绘制顺序
Collections.sort(mPositiveChildren, comparator);
Collections.sort(mNegativeChildren, comparator);
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (mRadius == 0) {
super.dispatchDraw(canvas);
return;
}
if (mDependency != null && !mCheckedDependencyOffset) {
int[] location = new int[2];
int[] dependencyLocation = new int[2];
getLocationOnScreen(location);
mDependency.getLocationOnScreen(dependencyLocation);
mDependencyOffset[0] = dependencyLocation[0] + mDependency.getCenterX() - (location[0] + getCenterX());
mDependencyOffset[1] = dependencyLocation[1] + mDependency.getCenterY() - (location[1] + getCenterY());
mCheckedDependencyOffset = true;
}
if (!mReverse) {
if (mRotateDegree > 90 || mRotateDegree <= -90) {
drawChildren(canvas, mNegativeChildren, mPositiveChildren);
} else {
drawChildren(canvas, mPositiveChildren, mNegativeChildren);
}
} else {
if (mRotateDegree >= 90 || mRotateDegree < -90) {
drawChildren(canvas, mPositiveChildren, mNegativeChildren);
} else {
drawChildren(canvas, mNegativeChildren, mPositiveChildren);
}
}
}
private void drawChildren(Canvas canvas, List<View> frontChildren, List<View> backChildren) {
if (!mHideBack) {
final int c0 = backChildren.size();
for (int i = c0 - 1; i >= 0; i--) {
drawChild(canvas, backChildren.get(i));
}
}
final int c1 = frontChildren.size();
for (int i = 0; i < c1; i++) {
drawChild(canvas, frontChildren.get(i));
}
}
private void drawChild(Canvas canvas, View child) {
final long drawingTime = getDrawingTime();
final LayoutParams p = (LayoutParams) child.getLayoutParams();
final int depth = mReverse ? -p.depth : p.depth;
mCamera.save();
mCamera.rotateY(mRotateDegree);
mCamera.translate(0, 0, -depth);
mCamera.getMatrix(mMatrix);
mCamera.restore();
// fix camera bug
mMatrix.getValues(mValues);
mValues[6] = mValues[6] / mDensity;
mValues[7] = mValues[7] / mDensity;
mMatrix.setValues(mValues);
mMatrix.postRotate(mDirection, 0, 0);
mMatrix.postTranslate(mCenter.x + mDependencyOffset[0], mCenter.y + mDependencyOffset[1]);
mMatrix.preRotate(-mDirection, 0, 0);
mMatrix.preTranslate(-mCenter.x - mDependencyOffset[0], -mCenter.y - mDependencyOffset[1]);
if (depth < 0) {
if (mOrientation == HORIZONTAL) {
mMatrix.preScale(-1, 1, mCenter.x, mCenter.y);
} else if (mOrientation == VERTICAL) {
mMatrix.preScale(1, -1, mCenter.x, mCenter.y);
}
}
canvas.save();
canvas.concat(mMatrix);
drawChild(canvas, child, drawingTime);
canvas.restore();
}
public int makeRoatateDegreeWithinRange(int degree) {
while (degree <= -180) {
degree += 360;
}
while (degree > 180) {
degree -= 360;
}
return degree;
}
public int makeDirectionWithinRange(int direction) {
while (direction <= -180) {
direction += 360;
}
while (direction > 180) {
direction -= 360;
}
return direction;
}
/**
* @return 当fitBounds为true时, 该childview的最小宽高
*/
public int getMinimumBoundsSize() {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getContext().getResources().getDisplayMetrics());
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
if (p instanceof LayoutParams) {
return new LayoutParams((LayoutParams) p);
} else if (p instanceof MarginLayoutParams) {
return new LayoutParams((MarginLayoutParams) p);
}
return new LayoutParams(p);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
public static clreplaced LayoutParams extends MarginLayoutParams {
/**
* 视图在z轴的位置
* 该z轴以指向观察者的方向为正方向,与{@link Camera}的z轴方向相反
* {@link SphereLayout}的直系子视图必须设置depth属性
*/
public int depth;
/**
* 为true时,子视图会宽高适配当前所处{@link #depth}层级的圆的直径且无视自身margin属性
*/
public boolean fitBounds;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.SphereLayout_Layout);
depth = a.getLayoutDimension(R.styleable.SphereLayout_Layout_layout_depth, "layout_depth");
fitBounds = a.getBoolean(R.styleable.SphereLayout_Layout_layout_fitBounds, false);
a.recycle();
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(LayoutParams p) {
super(p);
depth = p.depth;
fitBounds = p.fitBounds;
}
public LayoutParams(MarginLayoutParams p) {
super(p);
}
public LayoutParams(ViewGroup.LayoutParams p) {
super(p);
}
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SphereSavedState ss = new SphereSavedState(superState);
ss.radius = mRadius;
ss.orientation = mOrientation;
ss.hideBack = mHideBack;
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SphereSavedState ss = (SphereSavedState) state;
mRadius = ss.radius;
mOrientation = ss.orientation;
mHideBack = ss.hideBack;
super.onRestoreInstanceState(ss.getSuperState());
}
static clreplaced SphereSavedState extends BaseSavedState {
int radius;
int orientation;
boolean hideBack;
SphereSavedState(Parcelable superState) {
super(superState);
}
/**
* Constructor called from {@link #CREATOR}
*/
private SphereSavedState(Parcel in) {
super(in);
radius = in.readInt();
orientation = in.readInt();
hideBack = in.readInt() == 0 ? false : true;
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(radius);
out.writeInt(orientation);
out.writeInt(hideBack ? 1 : 0);
}
public static final Creator<SphereSavedState> CREATOR = new Creator<SphereSavedState>() {
public SphereSavedState createFromParcel(Parcel in) {
return new SphereSavedState(in);
}
public SphereSavedState[] newArray(int size) {
return new SphereSavedState[size];
}
};
}
private interface OnRotateListener {
void onRotate(int direction, int degree);
}
}
17
Source : FlipAnimation.java
with GNU Lesser General Public License v3.0
from starcor-company
with GNU Lesser General Public License v3.0
from starcor-company
/**
* Created by hy on 2015/1/26.
*/
public clreplaced FlipAnimation implements IXulAnimation {
Camera _camera = new Camera();
Matrix _matrix = new Matrix();
protected XulViewRender _render;
float _angle = 0;
public FlipAnimation(XulViewRender render) {
this._render = render;
_render.addAnimation(this);
}
@Override
public boolean updateAnimation(long timestamp) {
if (_render == null) {
return false;
}
_angle += 3;
_angle %= 360.0;
_render.markDirtyView();
return true;
}
public void setAngle(float angle) {
_angle = angle;
}
public float getAngle() {
return _angle;
}
public void preDraw(XulDC dc, float x, float y, float cx, float cy) {
dc.save();
_camera.save();
_camera.rotateY(_angle);
_camera.getMatrix(_matrix);
_matrix.preTranslate(-x - cx / 2.0f, -y - cy / 2.0f);
_matrix.postTranslate(+x + cx / 2.0f, y + cy / 2.0f);
dc.setMatrix(_matrix);
}
public void postDraw(XulDC dc, float x, float y, float cx, float cy) {
_camera.restore();
dc.restore();
}
}
17
Source : DiceLoadingView.java
with MIT License
from samlss
with MIT License
from samlss
/**
* @author SamLeung
* @e-mail [email protected]
* @github https://github.com/samlss
* @csdn https://blog.csdn.net/Samlss
* @description A dice 3D rotation loading view.
*/
public clreplaced DiceLoadingView extends ViewGroup {
private final static int DEFAULT_DURATION = 2500;
// 200 px
private final static int DEFAULT_SIZE = 200;
// The fixed child count.
private final static int FIXED_CHILD_COUNT = 7;
/**
* The real width of this view.
*/
private int mRealWidth;
/**
* The real height of this view.
*/
private int mRealHeight;
/**
* The width of child, need to subtract {@link #getPaddingLeft()} ()}, {@link #getPaddingRight()}.
*/
private int mChildWidth;
/**
* The height of child, need to subtract {@link #getPaddingTop()}, {@link #getPaddingBottom()}.
*/
private int mChildHeight;
private int mFirstSideDiceNumber = DiceView.NUMBER_ONE;
private int mFirstSidePointColor = DiceView.DEFAULT_COLOR;
private int mFirstSideDiceBgColor = DiceView.DEFAULT_BG_COLOR;
private int mFirstSideDiceBorderColor = DiceView.DEFAULT_COLOR;
private int mSecondSideDiceNumber = DiceView.NUMBER_FIVE;
private int mSecondSidePointColor = DiceView.DEFAULT_COLOR;
private int mSecondSideDiceBgColor = DiceView.DEFAULT_BG_COLOR;
private int mSecondSideDiceBorderColor = DiceView.DEFAULT_COLOR;
private int mThirdSideDiceNumber = DiceView.NUMBER_SIX;
private int mThirdSidePointColor = DiceView.DEFAULT_COLOR;
private int mThirdSideDiceBgColor = DiceView.DEFAULT_BG_COLOR;
private int mThirdSideDiceBorderColor = DiceView.DEFAULT_COLOR;
private int mFourthSideDiceNumber = DiceView.NUMBER_TWO;
private int mFourthSidePointColor = DiceView.DEFAULT_COLOR;
private int mFourthSideDiceBgColor = DiceView.DEFAULT_BG_COLOR;
private int mFourthSideDiceBorderColor = DiceView.DEFAULT_COLOR;
private Camera mCamera;
private Matrix mMatrix;
private ValueAnimator mValueAnimator;
private int mAnimatedValue;
private long mAnimatorPlayTime;
private DiceView[] mDiceViews = new DiceView[FIXED_CHILD_COUNT];
private TimeInterpolator mInterpolator = new AccelerateDecelerateInterpolator();
private long mDuration = DEFAULT_DURATION;
public DiceLoadingView(Context context) {
this(context, null);
}
public DiceLoadingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DiceLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttr(attrs);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public DiceLoadingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
parseAttr(attrs);
init();
}
private void parseAttr(AttributeSet attrs) {
if (attrs == null) {
return;
}
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.DiceLoadingView);
mDuration = typedArray.getInteger(R.styleable.DiceLoadingView_animDuration, DEFAULT_DURATION);
if (mDuration < 0) {
mDuration = DEFAULT_DURATION;
}
int interpolatorValue = typedArray.getInt(R.styleable.DiceLoadingView_animInterpolator, 0);
switch(interpolatorValue) {
case 0:
mInterpolator = new AccelerateDecelerateInterpolator();
break;
case 1:
mInterpolator = new AccelerateInterpolator();
break;
case 2:
mInterpolator = new DecelerateInterpolator();
break;
case 3:
mInterpolator = new BounceInterpolator();
break;
case 4:
mInterpolator = new CycleInterpolator(0.5f);
break;
case 5:
mInterpolator = new LinearInterpolator();
break;
case 6:
mInterpolator = new AnticipateOvershootInterpolator();
break;
case 7:
mInterpolator = new AnticipateInterpolator();
break;
case 8:
mInterpolator = new OvershootInterpolator();
break;
default:
break;
}
mFirstSideDiceNumber = typedArray.getInteger(R.styleable.DiceLoadingView_firstSideDiceNumber, DiceView.NUMBER_ONE);
mFirstSidePointColor = typedArray.getColor(R.styleable.DiceLoadingView_firstSideDicePointColor, DiceView.DEFAULT_COLOR);
mFirstSideDiceBgColor = typedArray.getColor(R.styleable.DiceLoadingView_firstSideDiceBgColor, DiceView.DEFAULT_BG_COLOR);
mFirstSideDiceBorderColor = typedArray.getColor(R.styleable.DiceLoadingView_firstSideDiceBorderColor, DiceView.DEFAULT_COLOR);
mSecondSideDiceNumber = typedArray.getInteger(R.styleable.DiceLoadingView_secondSideDiceNumber, DiceView.NUMBER_FIVE);
mSecondSidePointColor = typedArray.getColor(R.styleable.DiceLoadingView_secondSideDicePointColor, DiceView.DEFAULT_COLOR);
mSecondSideDiceBgColor = typedArray.getColor(R.styleable.DiceLoadingView_secondSideDiceBgColor, DiceView.DEFAULT_BG_COLOR);
mSecondSideDiceBorderColor = typedArray.getColor(R.styleable.DiceLoadingView_secondSideDiceBorderColor, DiceView.DEFAULT_COLOR);
mThirdSideDiceNumber = typedArray.getInteger(R.styleable.DiceLoadingView_thirdSideDiceNumber, DiceView.NUMBER_SIX);
mThirdSidePointColor = typedArray.getColor(R.styleable.DiceLoadingView_thirdSideDicePointColor, DiceView.DEFAULT_COLOR);
mThirdSideDiceBgColor = typedArray.getColor(R.styleable.DiceLoadingView_thirdSideDiceBgColor, DiceView.DEFAULT_BG_COLOR);
mThirdSideDiceBorderColor = typedArray.getColor(R.styleable.DiceLoadingView_thirdSideDiceBorderColor, DiceView.DEFAULT_COLOR);
mFourthSideDiceNumber = typedArray.getInteger(R.styleable.DiceLoadingView_fourthSideDiceNumber, DiceView.NUMBER_TWO);
mFourthSidePointColor = typedArray.getColor(R.styleable.DiceLoadingView_fourthSideDicePointColor, DiceView.DEFAULT_COLOR);
mFourthSideDiceBgColor = typedArray.getColor(R.styleable.DiceLoadingView_fourthSideDiceBgColor, DiceView.DEFAULT_BG_COLOR);
mFourthSideDiceBorderColor = typedArray.getColor(R.styleable.DiceLoadingView_fourthSideDiceBorderColor, DiceView.DEFAULT_COLOR);
typedArray.recycle();
}
private void init() {
mCamera = new Camera();
mMatrix = new Matrix();
addChildViews();
}
private void addChildViews() {
mDiceViews[0] = new DiceView(getContext());
mDiceViews[0].setNumber(mFourthSideDiceNumber);
mDiceViews[0].setPointColor(mFourthSidePointColor);
mDiceViews[0].setBgColor(mFourthSideDiceBgColor);
mDiceViews[0].setBorderColor(mFourthSideDiceBorderColor);
mDiceViews[1] = new DiceView(getContext());
mDiceViews[1].setNumber(mFirstSideDiceNumber);
mDiceViews[1].setPointColor(mFirstSidePointColor);
mDiceViews[1].setBgColor(mFirstSideDiceBgColor);
mDiceViews[1].setBorderColor(mFirstSideDiceBorderColor);
mDiceViews[2] = new DiceView(getContext());
mDiceViews[2].setNumber(mSecondSideDiceNumber);
mDiceViews[2].setPointColor(mSecondSidePointColor);
mDiceViews[2].setBgColor(mSecondSideDiceBgColor);
mDiceViews[2].setBorderColor(mSecondSideDiceBorderColor);
mDiceViews[3] = new DiceView(getContext());
mDiceViews[3].setNumber(mThirdSideDiceNumber);
mDiceViews[3].setPointColor(mThirdSidePointColor);
mDiceViews[3].setBgColor(mThirdSideDiceBgColor);
mDiceViews[3].setBorderColor(mThirdSideDiceBorderColor);
mDiceViews[4] = new DiceView(getContext());
mDiceViews[4].setNumber(mFourthSideDiceNumber);
mDiceViews[4].setPointColor(mFourthSidePointColor);
mDiceViews[4].setBgColor(mFourthSideDiceBgColor);
mDiceViews[4].setBorderColor(mFourthSideDiceBorderColor);
mDiceViews[5] = new DiceView(getContext());
mDiceViews[5].setNumber(mFirstSideDiceNumber);
mDiceViews[5].setPointColor(mFirstSidePointColor);
mDiceViews[5].setBgColor(mFirstSideDiceBgColor);
mDiceViews[5].setBorderColor(mFirstSideDiceBorderColor);
mDiceViews[6] = new DiceView(getContext());
mDiceViews[6].setNumber(mSecondSideDiceNumber);
mDiceViews[6].setPointColor(mSecondSidePointColor);
mDiceViews[6].setBgColor(mSecondSideDiceBgColor);
mDiceViews[6].setBorderColor(mSecondSideDiceBorderColor);
for (DiceView diceView : mDiceViews) {
addView(diceView, -1);
}
}
/**
* In order not to cut off the dice border, check and set padding here.
*/
private void checkPadding(int width, int height) {
int minSize = Math.min(width, height);
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
int defPadding = minSize / 8;
if (paddingLeft < defPadding) {
paddingLeft = defPadding;
}
if (paddingRight < defPadding) {
paddingRight = defPadding;
}
if (paddingTop < defPadding) {
paddingTop = defPadding;
}
if (paddingBottom < defPadding) {
paddingBottom = defPadding;
}
setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
@Override
public void addView(View child, int index, LayoutParams params) {
if (child instanceof DiceView == false) {
return;
}
super.addView(child, index, params);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int w = widthSpecSize;
int h = heightSpecSize;
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
w = DEFAULT_SIZE;
h = DEFAULT_SIZE;
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
w = DEFAULT_SIZE;
h = heightSpecSize;
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
w = widthSpecSize;
h = DEFAULT_SIZE;
}
mRealWidth = w;
mRealHeight = h;
setMeasuredDimension(w, h);
checkPadding(w, h);
mChildWidth = w - getPaddingLeft() - getPaddingRight();
mChildHeight = h - getPaddingTop() - getPaddingBottom();
measureChildren(MeasureSpec.makeMeasureSpec(mRealWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(mRealHeight, MeasureSpec.EXACTLY));
}
@Override
protected void onLayout(boolean b, int left, int top, int right, int bottom) {
int childLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
child.layout(childLeft, paddingTop, childLeft + child.getMeasuredWidth(), paddingTop + child.getMeasuredHeight());
childLeft = childLeft + child.getMeasuredWidth();
}
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setupAnimator();
}
private void setupAnimator() {
release();
if (getChildCount() < FIXED_CHILD_COUNT) {
return;
}
mValueAnimator = ValueAnimator.ofInt(0, mChildWidth * 4);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatedValue = (int) valueAnimator.getAnimatedValue();
scrollTo(mAnimatedValue + mChildWidth, 0);
invalidate();
}
});
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationRepeat(Animator animation) {
scrollTo(mChildWidth, 0);
}
});
mValueAnimator.setInterpolator(mInterpolator);
mValueAnimator.setDuration(mDuration);
mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
mValueAnimator.start();
}
@Override
protected void dispatchDraw(Canvas canvas) {
for (int i = 0; i < getChildCount(); i++) {
drawChild(canvas, i, getChildAt(i));
}
}
/**
* Draw the child.
*
* @param canvas
* @param index
* @param child
*/
private void drawChild(Canvas canvas, int index, View child) {
int childLeft = mChildWidth * index + getPaddingLeft();
int scrollX = getScrollX() + getPaddingLeft();
if (scrollX + mChildWidth < childLeft) {
return;
}
if (childLeft < scrollX - mChildWidth) {
return;
}
float centerX = (scrollX > childLeft) ? childLeft + mChildWidth : childLeft;
float centerY = mChildHeight / 2;
float degree = -90 * (scrollX - childLeft) / mChildWidth;
if (degree > 90 || degree < -90) {
return;
}
canvas.save();
mCamera.save();
mCamera.rotateY(degree);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-centerX, -centerY);
mMatrix.postTranslate(centerX, centerY);
canvas.concat(mMatrix);
drawChild(canvas, child, getDrawingTime());
canvas.restore();
}
/**
* Pause the animation.
*/
public void pause() {
if (mValueAnimator != null && mValueAnimator.isRunning()) {
mAnimatorPlayTime = mValueAnimator.getCurrentPlayTime();
mValueAnimator.cancel();
}
}
/**
* Resume the animation.
*/
public void resume() {
if (mValueAnimator != null && !mValueAnimator.isRunning()) {
mValueAnimator.setCurrentPlayTime(mAnimatorPlayTime);
mValueAnimator.start();
}
}
/**
* Start the animation.
*/
public void start() {
mAnimatorPlayTime = 0;
if (mValueAnimator != null) {
mValueAnimator.start();
}
}
/**
* Cancel the animation.
*/
public void stop() {
if (mValueAnimator != null) {
mValueAnimator.cancel();
}
}
/**
* Release this view when you do not need it.
*/
public void release() {
stop();
if (mValueAnimator != null) {
mValueAnimator.removeAllUpdateListeners();
mValueAnimator.removeAllListeners();
}
}
/**
* Get the dice number of the first dice side.
*/
public int getFirstSideDiceNumber() {
return mFirstSideDiceNumber;
}
/**
* Set the dice number{1-6} of the first dice side.
*/
public void setFirstSideDiceNumber(int firstSideDiceNumber) {
this.mFirstSideDiceNumber = firstSideDiceNumber;
mDiceViews[1].setNumber(mFirstSideDiceNumber);
mDiceViews[5].setNumber(mFirstSideDiceNumber);
}
/**
* Get the point color of the first dice side.
*/
public int getFirstSidePointColor() {
return mFirstSidePointColor;
}
/**
* Set the point color of the first dice side.
*/
public void setFirstSidePointColor(int firstSidePointColor) {
this.mFirstSidePointColor = firstSidePointColor;
mDiceViews[1].setPointColor(mFirstSidePointColor);
mDiceViews[5].setPointColor(mFirstSidePointColor);
}
/**
* Get the bg color of the first dice side.
*/
public int getFirstSideDiceBgColor() {
return mFirstSideDiceBgColor;
}
/**
* Set the bg color of the first dice side.
*/
public void setFirstSideDiceBgColor(int firstSideDiceBgColor) {
this.mFirstSideDiceBgColor = firstSideDiceBgColor;
mDiceViews[1].setBgColor(mFirstSideDiceBgColor);
mDiceViews[5].setBgColor(mFirstSideDiceBgColor);
}
/**
* Get the border color of the first dice side.
*/
public int getFirstSideDiceBorderColor() {
return mFirstSideDiceBorderColor;
}
/**
* Set the border color of the first dice side.
*/
public void setFirstSideDiceBorderColor(int firstSideDiceBorderColor) {
this.mFirstSideDiceBorderColor = firstSideDiceBorderColor;
mDiceViews[1].setBorderColor(mFirstSideDiceBorderColor);
mDiceViews[5].setBorderColor(mFirstSideDiceBorderColor);
}
/**
* Set the dice number of the second dice side.
*/
public int getSecondSideDiceNumber() {
return mSecondSideDiceNumber;
}
/**
* Set the dice number{1-6} of the second dice side.
*/
public void setSecondSideDiceNumber(int secondSideDiceNumber) {
this.mSecondSideDiceNumber = secondSideDiceNumber;
mDiceViews[2].setNumber(mSecondSideDiceNumber);
mDiceViews[6].setNumber(mSecondSideDiceNumber);
}
/**
* Get the point color of the second dice side.
*/
public int getSecondSidePointColor() {
return mSecondSidePointColor;
}
/**
* Set the point color of the second dice side.
*/
public void setSecondSidePointColor(int secondSidePointColor) {
this.mSecondSidePointColor = secondSidePointColor;
mDiceViews[2].setPointColor(mSecondSidePointColor);
mDiceViews[6].setPointColor(mSecondSidePointColor);
}
/**
* Get the bg color of the second dice side.
*/
public int getSecondSideDiceBgColor() {
return mSecondSideDiceBgColor;
}
/**
* Set the bg color of the second dice side.
*/
public void setSecondSideDiceBgColor(int secondSideDiceBgColor) {
this.mSecondSideDiceBgColor = secondSideDiceBgColor;
mDiceViews[2].setBgColor(mSecondSideDiceBgColor);
mDiceViews[6].setBgColor(mSecondSideDiceBgColor);
}
/**
* Get the border color of the second dice side.
*/
public int getSecondSideDiceBorderColor() {
return mSecondSideDiceBorderColor;
}
/**
* Set the border color of the second dice side.
*/
public void setSecondSideDiceBorderColor(int secondSideDiceBorderColor) {
this.mSecondSideDiceBorderColor = secondSideDiceBorderColor;
mDiceViews[2].setBorderColor(mSecondSideDiceBorderColor);
mDiceViews[6].setBorderColor(mSecondSideDiceBorderColor);
}
/**
* Get the dice number of the third dice side.
*/
public int getThirdSideDiceNumber() {
return mThirdSideDiceNumber;
}
/**
* Set the dice number{1-6} of the third dice side.
*/
public void setThirdSideDiceNumber(int thirdSideDiceNumber) {
this.mThirdSideDiceNumber = thirdSideDiceNumber;
mDiceViews[3].setNumber(mThirdSideDiceNumber);
}
/**
* Get the point color of the third dice side.
*/
public int getThirdSidePointColor() {
return mThirdSidePointColor;
}
/**
* Set the point color of the third dice side.
*/
public void setThirdSidePointColor(int thirdSidePointColor) {
this.mThirdSidePointColor = thirdSidePointColor;
mDiceViews[3].setPointColor(mThirdSidePointColor);
}
/**
* Get the bg color of the third dice side.
*/
public int getThirdSideDiceBgColor() {
return mThirdSideDiceBgColor;
}
/**
* Set the bg color of the third dice side.
*/
public void setThirdSideDiceBgColor(int thirdSideDiceBgColor) {
this.mThirdSideDiceBgColor = thirdSideDiceBgColor;
mDiceViews[3].setBgColor(mThirdSideDiceBgColor);
}
/**
* Get the border color of the third dice side.
*/
public int getThirdSideDiceBorderColor() {
return mThirdSideDiceBorderColor;
}
/**
* Set the border color of the third dice side.
*/
public void setThirdSideDiceBorderColor(int thirdSideDiceBorderColor) {
this.mThirdSideDiceBorderColor = thirdSideDiceBorderColor;
mDiceViews[3].setBorderColor(mThirdSideDiceBorderColor);
}
/**
* Get the dice number of the fourth dice side.
*/
public int getFourthSideDiceNumber() {
return mFourthSideDiceNumber;
}
/**
* Set the dice number{1-6} of the fourth dice side.
*/
public void setFourthSideDiceNumber(int fourthSideDiceNumber) {
this.mFourthSideDiceNumber = fourthSideDiceNumber;
mDiceViews[0].setNumber(mFourthSideDiceNumber);
mDiceViews[4].setNumber(mFourthSideDiceNumber);
}
/**
* Get the point color of the fourth dice side.
*/
public int getFourthSidePointColor() {
return mFourthSidePointColor;
}
/**
* Set the point color of the fourth dice side.
*/
public void setFourthSidePointColor(int fourthSidePointColor) {
this.mFourthSidePointColor = fourthSidePointColor;
mDiceViews[0].setPointColor(mFourthSidePointColor);
mDiceViews[4].setPointColor(mFourthSidePointColor);
}
/**
* Get the bg color of the fourth dice side.
*/
public int getFourthSideDiceBgColor() {
return mFourthSideDiceBgColor;
}
/**
* Set the bg color of the fourth dice side.
*/
public void setFourthSideDiceBgColor(int fourthSideDiceBgColor) {
this.mFourthSideDiceBgColor = fourthSideDiceBgColor;
mDiceViews[0].setBgColor(mFourthSideDiceBgColor);
mDiceViews[4].setBgColor(mFourthSideDiceBgColor);
}
/**
* Get the border color of the fourth dice side.
*/
public int getFourthSideDiceBorderColor() {
return mFourthSideDiceBorderColor;
}
/**
* Set the border color of the fourth dice side.
*/
public void setFourthSideDiceBorderColor(int fourthSideDiceBorderColor) {
this.mFourthSideDiceBorderColor = fourthSideDiceBorderColor;
mDiceViews[0].setBorderColor(mFourthSideDiceBorderColor);
mDiceViews[4].setBorderColor(mFourthSideDiceBorderColor);
}
/**
* Get the animation's interpolator.
*/
public TimeInterpolator getInterpolator() {
return mInterpolator;
}
/**
* Set the animation's interpolator.
*/
public void setInterpolator(TimeInterpolator mInterpolator) {
this.mInterpolator = mInterpolator;
setupAnimator();
}
/**
* Get the animation 's duration.
*/
public long getDuration() {
return mDuration;
}
/**
* Set the animation 's duration.
*/
public void setDuration(long duration) {
this.mDuration = duration;
setupAnimator();
}
}
17
Source : CubeLoadingView.java
with MIT License
from samlss
with MIT License
from samlss
/**
* @author SamLeung
* @e-mail [email protected]
* @github https://github.com/samlss
* @csdn https://blog.csdn.net/Samlss
* @description A cube 3D rotation loading view.
*/
public clreplaced CubeLoadingView extends ViewGroup {
// 200 px
private final static int DEFAULT_SIZE = 200;
// The fixed child count.
private final static int FIXED_CHILD_COUNT = 5;
private final static int DEFAULT_FIRST_COLOR = Color.parseColor("#F8C66B");
private final static int DEFAULT_SECOND_COLOR = Color.parseColor("#00AACF");
private final static int DEFAULT_THIRD_COLOR = Color.parseColor("#214C59");
private final static int DEFAULT_FOURTH_COLOR = Color.parseColor("#00B39F");
private int mWidth;
private int mHeight;
private Camera mCamera;
private Matrix mMatrix;
private ValueAnimator mValueAnimator;
private int mAnimatedValue;
private long mAnimatorPlayTime;
private View mSide1View;
private View mSide2View;
private View mSide3View;
private View mSide4View;
private View mSide5View;
private int mFirstSideColor = DEFAULT_FIRST_COLOR;
private int mSecondSideColor = DEFAULT_SECOND_COLOR;
private int mThirdSideColor = DEFAULT_THIRD_COLOR;
private int mFourthSideColor = DEFAULT_FOURTH_COLOR;
public CubeLoadingView(Context context) {
this(context, null);
}
public CubeLoadingView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CubeLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttr(attrs);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CubeLoadingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
parseAttr(attrs);
init();
}
private void parseAttr(AttributeSet attrs) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CubeLoadingView);
mFirstSideColor = typedArray.getColor(R.styleable.CubeLoadingView_firstSideColor, DEFAULT_FIRST_COLOR);
mSecondSideColor = typedArray.getInteger(R.styleable.CubeLoadingView_secondSideColor, DEFAULT_SECOND_COLOR);
mThirdSideColor = typedArray.getInteger(R.styleable.CubeLoadingView_thirdSideColor, DEFAULT_THIRD_COLOR);
mFourthSideColor = typedArray.getInteger(R.styleable.CubeLoadingView_fourthSideColor, DEFAULT_FOURTH_COLOR);
typedArray.recycle();
}
private void init() {
mCamera = new Camera();
mMatrix = new Matrix();
addChildViews();
}
private void addChildViews() {
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mSide1View = new View(getContext());
mSide2View = new View(getContext());
mSide3View = new View(getContext());
mSide4View = new View(getContext());
mSide5View = new View(getContext());
mSide1View.setBackgroundColor(mFirstSideColor);
mSide5View.setBackgroundColor(mFirstSideColor);
mSide2View.setBackgroundColor(mSecondSideColor);
mSide3View.setBackgroundColor(mThirdSideColor);
mSide4View.setBackgroundColor(mFourthSideColor);
addViewInLayout(mSide1View, -1, layoutParams);
addViewInLayout(mSide2View, -1, layoutParams);
addViewInLayout(mSide3View, -1, layoutParams);
addViewInLayout(mSide4View, -1, layoutParams);
addViewInLayout(mSide5View, -1, layoutParams);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int mWidth = DEFAULT_SIZE;
int mHeight = DEFAULT_SIZE;
boolean isWidthWrap = getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT;
boolean isHeightWrap = getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT;
if (!isWidthWrap && !isHeightWrap) {
return;
}
setMeasuredDimension(isWidthWrap ? mWidth : widthSize, isHeightWrap ? mHeight : heightSize);
}
@Override
protected void onLayout(boolean b, int left, int top, int right, int bottom) {
int childTop = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
child.layout(0, childTop, child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
childTop = childTop + child.getMeasuredHeight();
}
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
release();
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
setupAnimator();
}
private void setupAnimator() {
if (getChildCount() < FIXED_CHILD_COUNT) {
return;
}
mValueAnimator = ValueAnimator.ofInt(0, mHeight * 4);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatedValue = (int) valueAnimator.getAnimatedValue();
scrollTo(0, mAnimatedValue);
invalidate();
}
});
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationRepeat(Animator animation) {
scrollTo(0, 0);
}
});
mValueAnimator.setInterpolator(new AnticipateOvershootInterpolator(0.8f));
mValueAnimator.setDuration(2500);
mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
mValueAnimator.start();
}
@Override
protected void dispatchDraw(Canvas canvas) {
for (int i = 0; i < getChildCount(); i++) {
drawChild(canvas, i, getChildAt(i));
}
}
/**
* Draw the child.
*
* @param canvas
* @param index
* @param child
*/
private void drawChild(Canvas canvas, int index, View child) {
int childTop = mHeight * index;
if (getScrollY() + mHeight < childTop) {
return;
}
if (childTop < getScrollY() - mHeight) {
return;
}
float centerX = mWidth / 2;
float centerY = (getScrollY() > childTop) ? childTop + mHeight : childTop;
float degree = 90 * (getScrollY() - childTop) / mHeight;
if (degree > 90 || degree < -90) {
return;
}
canvas.save();
mCamera.save();
mCamera.rotateX(degree);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-centerX, -centerY);
mMatrix.postTranslate(centerX, centerY);
canvas.concat(mMatrix);
drawChild(canvas, child, getDrawingTime());
canvas.restore();
}
public int getFirstSideColor() {
return mFirstSideColor;
}
public int getSecondSideColor() {
return mSecondSideColor;
}
public int getThirdSideColor() {
return mThirdSideColor;
}
public int getFourthSideColor() {
return mFourthSideColor;
}
/**
* Set the color of first side.
*/
public void setFirstSideColor(int firstSideColor) {
this.mFirstSideColor = firstSideColor;
mSide1View.setBackgroundColor(mFirstSideColor);
mSide5View.setBackgroundColor(mFirstSideColor);
invalidate();
}
/**
* Set the color of second side.
*/
public void setSecondSideColor(int secondSideColor) {
this.mSecondSideColor = secondSideColor;
mSide2View.setBackgroundColor(mSecondSideColor);
invalidate();
}
/**
* Set the color of third side.
*/
public void setThirdSideColor(int thirdSideColor) {
this.mThirdSideColor = thirdSideColor;
mSide3View.setBackgroundColor(mThirdSideColor);
invalidate();
}
/**
* Set the color of fourth side.
*/
public void setFourthSideColor(int fourthSideColor) {
this.mFourthSideColor = fourthSideColor;
mSide4View.setBackgroundColor(mFourthSideColor);
invalidate();
}
/**
* Pause the animation.
*/
public void pause() {
if (mValueAnimator != null && mValueAnimator.isRunning()) {
mAnimatorPlayTime = mValueAnimator.getCurrentPlayTime();
mValueAnimator.cancel();
}
}
/**
* Resume the animation.
*/
public void resume() {
if (mValueAnimator != null && !mValueAnimator.isRunning()) {
mValueAnimator.setCurrentPlayTime(mAnimatorPlayTime);
mValueAnimator.start();
}
}
/**
* Start the animation.
*/
public void start() {
mAnimatorPlayTime = 0;
if (mValueAnimator != null) {
mValueAnimator.start();
}
}
/**
* Cancel the animation.
*/
public void stop() {
if (mValueAnimator != null) {
mValueAnimator.cancel();
}
}
/**
* Release this view when you do not need it.
*/
public void release() {
stop();
if (mValueAnimator != null) {
mValueAnimator.removeAllUpdateListeners();
mValueAnimator.removeAllListeners();
}
}
}
17
Source : ShuttersConsumer.java
with Apache License 2.0
from luckybilly
with Apache License 2.0
from luckybilly
/**
* looks like shutters open and close
* @author billy.qi
*/
public clreplaced ShuttersConsumer extends SwipeConsumer {
protected final Camera mCamera;
protected Paint mPaint;
protected boolean mHorizontalSwiping;
protected int mBaseAlpha;
protected int lastScreenDirection = DIRECTION_NONE;
/**
* internal mark: refreshBitmapRunnable is working or not
*/
protected volatile boolean mRefreshing;
protected volatile Bitmap[] mScreenshots;
protected int mScrimColor;
protected int mLeavesCount = 5;
protected volatile boolean mRefreshable = true;
protected boolean mWaitForScreenshot = true;
/**
* refresh rate: 30 frames per second
*/
protected int refreshDelay = 1000 / 30;
public ShuttersConsumer() {
setReleaseMode(RELEASE_MODE_AUTO_OPEN_CLOSE);
mCamera = new Camera();
mCamera.setLocation(0, 0, -20);
mPaint = new Paint();
}
@Override
public void onDetachFromWrapper() {
super.onDetachFromWrapper();
setRefreshing(false);
recycleScreenshots();
layoutChildren();
}
@Override
public void onSwipeAccepted(int activePointerId, boolean settling, float initialMotionX, float initialMotionY) {
if (lastScreenDirection != mDirection) {
recycleScreenshots();
}
lastScreenDirection = mDirection;
lastRefreshTime = 0;
if ((mCurSwipeDistanceX == 0 && mCurSwipeDistanceY == 0)) {
int halfWidth = mWidth >> 1;
int halfHeight = mHeight >> 1;
mHorizontalSwiping = isHorizontalDirection();
if (!mOpenDistanceSpecified) {
if (mHorizontalSwiping) {
mOpenDistance = halfWidth;
} else {
mOpenDistance = halfHeight;
}
}
}
super.onSwipeAccepted(activePointerId, settling, initialMotionX, initialMotionY);
layoutChildren();
if (!mRefreshing) {
setRefreshing(true);
SwipeUtil.runInThreadPool(refreshBitmapRunnable);
}
}
private Runnable refreshWrapperRunnable = new Runnable() {
@Override
public void run() {
layoutChildren();
mWrapper.postInvalidate();
}
};
private Runnable refreshBitmapRunnable = new Runnable() {
@Override
public void run() {
refreshBitmap();
}
};
private clreplaced ScreenshotCreateRunnable implements Runnable {
int width, height;
int index;
Bitmap[] array;
CountDownLatch latch;
View srcView;
int scrollX, scrollY;
ScreenshotCreateRunnable(int width, int height, int index, Bitmap[] array, CountDownLatch latch, View srcView, int scrollX, int scrollY) {
this.width = width;
this.height = height;
this.index = index;
this.array = array;
this.latch = latch;
this.srcView = srcView;
this.scrollX = scrollX;
this.scrollY = scrollY;
}
@Override
public void run() {
boolean switchToMainThread = false;
try {
Bitmap screenshot = array[index];
if (screenshot == null || screenshot.isRecycled() || screenshot.getWidth() != width || screenshot.getHeight() != height) {
screenshot = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(screenshot);
canvas.translate(-srcView.getScrollX() - scrollX, -srcView.getScrollY() - scrollY);
// Draw background
Drawable bgDrawable = srcView.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
}
try {
srcView.draw(canvas);
array[index] = screenshot;
} catch (Exception e) {
if (Looper.myLooper() != Looper.getMainLooper()) {
switchToMainThread = true;
srcView.post(this);
}
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
if (!switchToMainThread) {
latch.countDown();
}
}
}
}
private long lastRefreshTime;
protected void refreshBitmap() {
if (lastRefreshTime == 0) {
lastRefreshTime = SystemClock.elapsedRealtime();
}
View v = mWrapper.getContentView();
final int leavesCount = this.mLeavesCount;
int width = (int) (mWidth * 1F / (mHorizontalSwiping ? leavesCount : 1) + 0.5F);
int height = (int) (mHeight * 1F / (mHorizontalSwiping ? 1 : leavesCount) + 0.5F);
int lastWidth = mHorizontalSwiping ? (mWidth - width * (leavesCount - 1)) : width;
int lastHeight = mHorizontalSwiping ? height : (mHeight - height * (leavesCount - 1));
// TODO reuse bitmap array. Tried to use buffer bitmap array, but a blink bug happens when refreshable enabled
Bitmap[] array = new Bitmap[leavesCount];
CountDownLatch latch = new CountDownLatch(leavesCount);
int scrollX = 0, scrollY = 0;
for (int i = 0; i < leavesCount; i++) {
if (mHorizontalSwiping) {
scrollX = width * i;
} else {
scrollY = height * i;
}
if (i == leavesCount - 1) {
if (lastWidth <= 0 || lastHeight <= 0) {
latch.countDown();
} else {
SwipeUtil.runInThreadPool(new ScreenshotCreateRunnable(lastWidth, lastHeight, i, array, latch, v, scrollX, scrollY));
}
} else {
SwipeUtil.runInThreadPool(new ScreenshotCreateRunnable(width, height, i, array, latch, v, scrollX, scrollY));
}
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!mSwiping && (mProgress <= 0 || mProgress >= 1)) {
setRefreshing(false);
}
if (!mRefreshing) {
return;
}
boolean hasNull = false;
for (Bitmap bitmap : array) {
if (bitmap == null) {
hasNull = true;
break;
}
}
if (!hasNull) {
this.mScreenshots = array;
}
v.post(refreshWrapperRunnable);
if (mRefreshable) {
long timePreplaced = SystemClock.elapsedRealtime() - lastRefreshTime;
lastRefreshTime = SystemClock.elapsedRealtime();
if (timePreplaced < refreshDelay) {
v.postDelayed(new Runnable() {
@Override
public void run() {
SwipeUtil.runInThreadPool(refreshBitmapRunnable);
}
}, refreshDelay - timePreplaced);
} else {
SwipeUtil.runInThreadPool(refreshBitmapRunnable);
}
} else {
setRefreshing(false);
}
}
private void setRefreshing(boolean refreshing) {
mRefreshing = refreshing;
}
private void layoutChildren() {
View contentView = mWrapper.getContentView();
if (mDirection == DIRECTION_NONE || mScreenshots == null && mWaitForScreenshot) {
contentView.layout(0, 0, mWidth, mHeight);
contentView.setVisibility(View.VISIBLE);
} else {
if (mRefreshable) {
contentView.layout(-9999, -9999, mWidth - 9999, mHeight - 9999);
} else {
contentView.setVisibility(View.GONE);
}
}
}
@Override
public void dispatchDraw(Canvas canvas) {
final Bitmap[] screenshots = this.mScreenshots;
if (mDirection == DIRECTION_NONE || screenshots == null || screenshots.length == 0) {
return;
}
if (mScrimColor != 0 && mBaseAlpha != 0) {
canvas.drawRect(0, 0, mWidth, mHeight, mPaint);
}
int halfW = mWidth >> 1;
int halfH = mHeight >> 1;
int leafSize = (int) ((mHorizontalSwiping ? mWidth : mHeight) * 1F / screenshots.length + 0.5F);
int halfLeafSize = leafSize >> 1;
int dir = (mDirection == DIRECTION_LEFT || mDirection == DIRECTION_BOTTOM) ? 1 : -1;
for (int i = 0; i < screenshots.length; i++) {
Bitmap screenshot = screenshots[i];
if (screenshot == null || screenshot.isRecycled()) {
continue;
}
canvas.save();
mCamera.save();
if (mHorizontalSwiping) {
canvas.translate(leafSize * i + halfLeafSize, halfH);
mCamera.rotateY(dir * 90 * mProgress);
mCamera.applyToCanvas(canvas);
canvas.translate(-halfLeafSize, 0);
canvas.drawBitmap(screenshot, 0, -halfH, null);
} else {
canvas.translate(halfW, leafSize * i + halfLeafSize);
mCamera.rotateX(dir * 90 * mProgress);
mCamera.applyToCanvas(canvas);
canvas.translate(0, -halfLeafSize);
canvas.drawBitmap(screenshot, -halfW, 0, null);
}
mCamera.restore();
canvas.restore();
}
}
@Override
public boolean onLayout(boolean changed, int left, int top, int right, int bottom) {
layoutChildren();
return true;
}
@Override
protected void onClosed() {
super.onClosed();
recycleScreenshots();
setRefreshing(false);
layoutChildren();
}
protected void recycleScreenshots() {
lastScreenDirection = DIRECTION_NONE;
mScreenshots = null;
}
@Override
protected void onDisplayDistanceChanged(int distanceXToDisplay, int distanceYToDisplay, int dx, int dy) {
if (mScrimColor != 0 && mBaseAlpha != 0) {
float progress = SmartSwipe.ensureBetween(mProgress, 0, 1F);
int alpha = (int) (mBaseAlpha * (1 - progress));
mPaint.setAlpha(alpha);
}
if (!mRefreshable) {
mWrapper.postInvalidate();
}
}
@Override
public int clampDistanceHorizontal(int distanceX, int dx) {
if (mScreenshots != null || !mWaitForScreenshot) {
return super.clampDistanceHorizontal(distanceX, dx);
}
return 0;
}
@Override
public int clampDistanceVertical(int distanceY, int dy) {
if (mScreenshots != null || !mWaitForScreenshot) {
return super.clampDistanceVertical(distanceY, dy);
}
return 0;
}
public int getScrimColor() {
return mScrimColor;
}
public ShuttersConsumer setScrimColor(int scrimColor) {
this.mScrimColor = scrimColor;
this.mPaint.setColor(scrimColor);
mBaseAlpha = (mScrimColor & 0xFF000000) >>> 24;
return this;
}
public int getLeavesCount() {
return mLeavesCount;
}
public ShuttersConsumer setLeavesCount(int leavesCount) {
int newCount = SmartSwipe.ensureBetween(leavesCount, 1, 100);
if (newCount != mLeavesCount) {
this.mLeavesCount = newCount;
recycleScreenshots();
}
return this;
}
public boolean isRefreshable() {
return mRefreshable;
}
public ShuttersConsumer setRefreshable(boolean refreshable) {
this.mRefreshable = refreshable;
return this;
}
public boolean isWaitForScreenshot() {
return mWaitForScreenshot;
}
/**
* if content view draw coat too much time, wait for screenshot is useful
* @param wait default is false, if set as true, do real swipe after screenshot has been done
* @return this
*/
public ShuttersConsumer setWaitForScreenshot(boolean wait) {
this.mWaitForScreenshot = wait;
return this;
}
public ShuttersConsumer setRefreshFrameRate(int frameRate) {
frameRate = SmartSwipe.ensureBetween(frameRate, 1, 60);
refreshDelay = 1000 / frameRate;
return this;
}
}
17
Source : FancyFlipView.java
with Apache License 2.0
from hencoder
with Apache License 2.0
from hencoder
public clreplaced FancyFlipView extends View {
private static final float IMAGE_SIZE = Utils.dpToPixel(150);
private static final float PADDING = Utils.dpToPixel(50);
private static final float FLIP_ANGLE = 45;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap bitmap;
Camera camera = new Camera();
private float leftFlip;
private float rightFlip;
private float flipRotation;
public float getLeftFlip() {
return leftFlip;
}
public void setLeftFlip(float leftFlip) {
this.leftFlip = leftFlip;
invalidate();
}
public float getRightFlip() {
return rightFlip;
}
public void setRightFlip(float rightFlip) {
this.rightFlip = rightFlip;
invalidate();
}
public float getFlipRotation() {
return flipRotation;
}
public void setFlipRotation(float flipRotation) {
this.flipRotation = flipRotation;
invalidate();
}
public FancyFlipView(Context context) {
super(context);
}
public FancyFlipView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public FancyFlipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
bitmap = Utils.getAvatar(getResources(), (int) IMAGE_SIZE);
camera.setLocation(0, 0, Utils.getCameraZ());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float offset = IMAGE_SIZE / 2 + PADDING;
// 左半边
camera.save();
camera.rotateY(leftFlip * FLIP_ANGLE);
canvas.save();
canvas.translate(offset, offset);
canvas.rotate(-flipRotation);
camera.applyToCanvas(canvas);
canvas.clipRect(0, -IMAGE_SIZE, -IMAGE_SIZE, IMAGE_SIZE);
canvas.rotate(flipRotation);
canvas.translate(-offset, -offset);
canvas.drawBitmap(bitmap, PADDING, PADDING, paint);
canvas.restore();
camera.restore();
// 右半边
camera.save();
camera.rotateY(-rightFlip * FLIP_ANGLE);
canvas.save();
canvas.translate(offset, offset);
canvas.rotate(-flipRotation);
camera.applyToCanvas(canvas);
canvas.clipRect(0, -IMAGE_SIZE, IMAGE_SIZE, IMAGE_SIZE);
canvas.rotate(flipRotation);
canvas.translate(-offset, -offset);
canvas.drawBitmap(bitmap, PADDING, PADDING, paint);
canvas.restore();
camera.restore();
}
}
17
Source : CameraView.java
with Apache License 2.0
from hencoder
with Apache License 2.0
from hencoder
public clreplaced CameraView extends View {
private static final float IMAGE_SIZE = Utils.dpToPixel(250);
private static final float OFFSET = Utils.dpToPixel(80);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap bitmap;
Camera camera = new Camera();
public CameraView(Context context) {
super(context);
}
public CameraView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CameraView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
bitmap = Utils.getAvatar(getResources(), (int) IMAGE_SIZE);
camera.rotateX(45);
// 8 * 72 = 576
camera.setLocation(0, 0, Utils.getCameraZ());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate((OFFSET + IMAGE_SIZE / 2), (OFFSET + IMAGE_SIZE / 2));
camera.applyToCanvas(canvas);
canvas.translate(-(OFFSET + IMAGE_SIZE / 2), -(OFFSET + IMAGE_SIZE / 2));
canvas.drawBitmap(bitmap, OFFSET, OFFSET, paint);
canvas.restore();
}
}
17
Source : BmpOverturnView.java
with Apache License 2.0
from faith-hb
with Apache License 2.0
from faith-hb
public clreplaced BmpOverturnView extends View {
public static final int IMAGE_WIDTH = DensityUtil.dp2px(180);
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap image;
Camera mCamera = new Camera();
float left = 0f, top = 0f;
float topFlip = 0f;
float bottomFlip = 0f;
float flipRotation = 0f;
// 将属性名单独包装下,便于外部和谐引用
public String getPropIsTopFlip() {
return "topFlip";
}
public String getPropIsBottomFlip() {
return "bottomFlip";
}
public String getPropFlipRotation() {
return "flipRotation";
}
public float getTopFlip() {
return topFlip;
}
public void setTopFlip(float topFlip) {
this.topFlip = topFlip;
invalidate();
}
public float getBottomFlip() {
return bottomFlip;
}
public void setBottomFlip(float bottomFlip) {
this.bottomFlip = bottomFlip;
invalidate();
}
public float getFlipRotation() {
return flipRotation;
}
public void setFlipRotation(float flipRotation) {
this.flipRotation = flipRotation;
invalidate();
}
public void propReset() {
setBottomFlip(0f);
setTopFlip(0f);
setFlipRotation(0f);
}
public BmpOverturnView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
image = Util.getAvatar(getResources(), IMAGE_WIDTH);
mCamera.setLocation(0, 0, Util.getZForCamera());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension((int) (IMAGE_WIDTH * 1.5f), (int) (IMAGE_WIDTH * 1.5f));
}
@Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
left = (getWidth() - IMAGE_WIDTH) / 2;
top = (getHeight() - IMAGE_WIDTH) / 2 - DensityUtil.dp2px(50);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 上半部分
canvas.save();
canvas.translate(left + IMAGE_WIDTH / 2, top + IMAGE_WIDTH / 2);
canvas.rotate(-flipRotation);
mCamera.save();
mCamera.rotateX(topFlip);
mCamera.applyToCanvas(canvas);
mCamera.restore();
canvas.clipRect(-IMAGE_WIDTH, -IMAGE_WIDTH, IMAGE_WIDTH, 0);
canvas.rotate(flipRotation);
canvas.translate(-(left + IMAGE_WIDTH / 2), -(top + IMAGE_WIDTH / 2));
canvas.drawBitmap(image, left, top, mPaint);
canvas.restore();
// 下半部分
canvas.save();
canvas.translate(left + IMAGE_WIDTH / 2, top + IMAGE_WIDTH / 2);
canvas.rotate(-flipRotation);
mCamera.save();
mCamera.rotateX(bottomFlip);
mCamera.applyToCanvas(canvas);
mCamera.restore();
canvas.clipRect(-IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_WIDTH);
canvas.rotate(flipRotation);
canvas.translate(-(left + IMAGE_WIDTH / 2), -(top + IMAGE_WIDTH / 2));
canvas.drawBitmap(image, left, top, mPaint);
canvas.restore();
}
}
16
Source : FaceFilterActivity.java
with Apache License 2.0
from gaetanozappi
with Apache License 2.0
from gaetanozappi
public clreplaced FaceFilterActivity extends AppCompatActivity {
TextGraphic mTextGraphic;
private final Thread observer = new Thread("observer") {
{
setDaemon(true);
}
public void run() {
while (!isInterrupted()) {
/*
TextGraphic mTextGraphic = new TextGraphic(mGraphicOverlay);
mGraphicOverlay.add(mTextGraphic);*/
// mTextGraphic.updateText(2);
}
}
};
private static final String TAG = "FaceTracker";
private CameraSource mCameraSource = null;
private int typeFace = 0;
private int typeFlash = 0;
private boolean flashmode = false;
private Camera camera;
private static final int[] MASK = { R.id.no_filter, R.id.hair, R.id.op, R.id.snap, R.id.glreplacedes2, R.id.glreplacedes3, R.id.glreplacedes4, R.id.glreplacedes5, R.id.mask, R.id.mask2, R.id.mask3, R.id.dog, R.id.cat2 };
private CameraSourcePreview mPreview;
private GraphicOverlay mGraphicOverlay;
private static final int RC_HANDLE_GMS = 9001;
// permission request codes need to be < 256
private static final int RC_HANDLE_CAMERA_PERM = 2;
// ==============================================================================================
// Activity Methods
// ==============================================================================================
/**
* Initializes the UI and initiates the creation of a face detector.
*/
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_face_filter);
mPreview = (CameraSourcePreview) findViewById(R.id.preview);
mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);
// mTextGraphic = new TextGraphic(mGraphicOverlay);
// mGraphicOverlay.add(mTextGraphic);
ImageButton face = (ImageButton) findViewById(R.id.face);
face.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (findViewById(R.id.scrollView).getVisibility() == GONE) {
findViewById(R.id.scrollView).setVisibility(View.VISIBLE);
((ImageButton) findViewById(R.id.face)).setImageResource(R.drawable.face_select);
} else {
findViewById(R.id.scrollView).setVisibility(GONE);
((ImageButton) findViewById(R.id.face)).setImageResource(R.drawable.face);
}
}
});
ImageButton no_filter = (ImageButton) findViewById(R.id.no_filter);
no_filter.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 0;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton hair = (ImageButton) findViewById(R.id.hair);
hair.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 1;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton op = (ImageButton) findViewById(R.id.op);
op.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 2;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton snap = (ImageButton) findViewById(R.id.snap);
snap.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 3;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton glreplacedes2 = (ImageButton) findViewById(R.id.glreplacedes2);
glreplacedes2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 4;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton glreplacedes3 = (ImageButton) findViewById(R.id.glreplacedes3);
glreplacedes3.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 5;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton glreplacedes4 = (ImageButton) findViewById(R.id.glreplacedes4);
glreplacedes4.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 6;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton glreplacedes5 = (ImageButton) findViewById(R.id.glreplacedes5);
glreplacedes5.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 7;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton mask = (ImageButton) findViewById(R.id.mask);
mask.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 8;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton mask2 = (ImageButton) findViewById(R.id.mask2);
mask2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 9;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton mask3 = (ImageButton) findViewById(R.id.mask3);
mask3.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 10;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton dog = (ImageButton) findViewById(R.id.dog);
dog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 11;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton cat2 = (ImageButton) findViewById(R.id.cat2);
cat2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background);
typeFace = 12;
findViewById(MASK[typeFace]).setBackgroundResource(R.drawable.round_background_select);
}
});
ImageButton button = (ImageButton) findViewById(R.id.change);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
final ImageButton flash = (ImageButton) findViewById(R.id.flash);
flash.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int blue;
if (flashmode == false) {
flashmode = true;
blue = 0;
} else {
flashmode = false;
blue = 255;
}
flash.setColorFilter(Color.argb(255, 255, 255, blue));
}
});
ImageButton camera = (ImageButton) findViewById(R.id.camera);
camera.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// takeImage();
onPause();
}
});
// Check for the camera permission before accessing the camera. If the
// permission is not granted yet, request permission.
int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (rc == PackageManager.PERMISSION_GRANTED) {
createCameraSource();
} else {
requestCameraPermission();
}
}
private void takeImage() {
try {
// openCamera(CameraInfo.CAMERA_FACING_BACK);
// releaseCameraSource();
// releaseCamera();
// openCamera(CameraInfo.CAMERA_FACING_BACK);
// setUpCamera(camera);
// Thread.sleep(1000);
mCameraSource.takePicture(null, new CameraSource.PictureCallback() {
private File imageFile;
@Override
public void onPictureTaken(byte[] bytes) {
try {
// convert byte array into bitmap
Bitmap loadedImage = null;
Bitmap rotatedBitmap = null;
loadedImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
// rotate Image
Matrix rotateMatrix = new Matrix();
rotateMatrix.postRotate(getWindowManager().getDefaultDisplay().getRotation());
rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0, loadedImage.getWidth(), loadedImage.getHeight(), rotateMatrix, false);
String state = Environment.getExternalStorageState();
File folder = null;
if (state.contains(Environment.MEDIA_MOUNTED)) {
folder = new File(Environment.getExternalStorageDirectory() + "/faceFilter");
} else {
folder = new File(Environment.getExternalStorageDirectory() + "/faceFilter");
}
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
java.util.Date date = new java.util.Date();
imageFile = new File(folder.getAbsolutePath() + File.separator + // + new Timestamp(date.getTime()).toString()
"Image.jpg");
imageFile.createNewFile();
} else {
Toast.makeText(getBaseContext(), "Image Not saved", Toast.LENGTH_SHORT).show();
return;
}
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
// save image into gallery
rotatedBitmap = resize(rotatedBitmap, 800, 600);
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
FileOutputStream fout = new FileOutputStream(imageFile);
fout.write(ostream.toByteArray());
fout.close();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, imageFile.getAbsolutePath());
// add this
setResult(Activity.RESULT_OK);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (Exception ex) {
}
}
private Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
if (maxHeight > 0 && maxWidth > 0) {
int width = image.getWidth();
int height = image.getHeight();
float ratioBitmap = (float) width / (float) height;
float ratioMax = (float) maxWidth / (float) maxHeight;
int finalWidth = maxWidth;
int finalHeight = maxHeight;
if (ratioMax > 1) {
finalWidth = (int) ((float) maxHeight * ratioBitmap);
} else {
finalHeight = (int) ((float) maxWidth / ratioBitmap);
}
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
return image;
} else {
return image;
}
}
/**
* Handles the requesting of the camera permission. This includes
* showing a "Snackbar" message of why the permission is needed then
* sending the request.
*/
private void requestCameraPermission() {
Log.w(TAG, "Camera permission is not granted. Requesting permission");
final String[] permissions = new String[] { Manifest.permission.CAMERA };
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
return;
}
final Activity thisActivity = this;
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(thisActivity, permissions, RC_HANDLE_CAMERA_PERM);
}
};
Snackbar.make(mGraphicOverlay, R.string.permission_camera_rationale, Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok, listener).show();
}
/**
* Creates and starts the camera. Note that this uses a higher resolution in comparison
* to other detection examples to enable the barcode detector to detect small barcodes
* at long distances.
*/
private void createCameraSource() {
Context context = getApplicationContext();
FaceDetector detector = new FaceDetector.Builder(context).setClreplacedificationType(FaceDetector.ALL_CLreplacedIFICATIONS).setLandmarkType(FaceDetector.ALL_LANDMARKS).setMode(FaceDetector.ACCURATE_MODE).build();
detector.setProcessor(new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory()).build());
// new MultiProcessor.Builder<>(new GraphicTextTrackerFactory()).build();
if (!detector.isOperational()) {
// Note: The first time that an app using face API is installed on a device, GMS will
// download a native library to the device in order to do detection. Usually this
// completes before the app is run for the first time. But if that download has not yet
// completed, then the above call will not detect any faces.
//
// isOperational() can be used to check if the required native library is currently
// available. The detector will automatically become operational once the library
// download completes on device.
Log.w(TAG, "Face detector dependencies are not yet available.");
}
mCameraSource = new CameraSource.Builder(context, detector).setRequestedPreviewSize(640, 480).setAutoFocusEnabled(true).setFacing(CameraSource.CAMERA_FACING_BACK).setRequestedFps(30.0f).build();
// observer.start();
/*
TextGraphic mTextGraphic = new TextGraphic(mGraphicOverlay);
mGraphicOverlay.add(mTextGraphic);
mTextGraphic.updateText(2);*/
}
/**
* Restarts the camera.
*/
@Override
protected void onResume() {
super.onResume();
startCameraSource();
}
/**
* Stops the camera.
*/
@Override
protected void onPause() {
super.onPause();
mPreview.stop();
}
/**
* Releases the resources replacedociated with the camera source, the replacedociated detector, and the
* rest of the processing pipeline.
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (mCameraSource != null) {
mCameraSource.release();
}
}
/**
* Callback for the result from requesting permissions. This method
* is invoked for every call on {@link #requestPermissions(String[], int)}.
* <p>
* <strong>Note:</strong> It is possible that the permissions request interaction
* with the user is interrupted. In this case you will receive empty permissions
* and results arrays which should be treated as a cancellation.
* </p>
*
* @param requestCode The request code preplaceded in {@link #requestPermissions(String[], int)}.
* @param permissions The requested permissions. Never null.
* @param grantResults The grant results for the corresponding permissions
* which is either {@link PackageManager#PERMISSION_GRANTED}
* or {@link PackageManager#PERMISSION_DENIED}. Never null.
* @see #requestPermissions(String[], int)
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode != RC_HANDLE_CAMERA_PERM) {
Log.d(TAG, "Got unexpected permission result: " + requestCode);
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Camera permission granted - initialize the camera source");
// we have permission, so create the camerasource
createCameraSource();
return;
}
Log.e(TAG, "Permission not granted: results len = " + grantResults.length + " Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)"));
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setreplacedle("Face Tracker sample").setMessage(R.string.no_camera_permission).setPositiveButton(R.string.ok, listener).show();
}
// ==============================================================================================
// Camera Source Preview
// ==============================================================================================
/**
* Starts or restarts the camera source, if it exists. If the camera source doesn't exist yet
* (e.g., because onResume was called before the camera source was created), this will be called
* again when the camera source is created.
*/
private void startCameraSource() {
// check that the device has play services available.
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext());
if (code != ConnectionResult.SUCCESS) {
Dialog dlg = GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS);
dlg.show();
}
if (mCameraSource != null) {
try {
mPreview.start(mCameraSource, mGraphicOverlay);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
mCameraSource.release();
mCameraSource = null;
}
}
}
private clreplaced GraphicTextTrackerFactory implements MultiProcessor.Factory<String> {
@Override
public Tracker<String> create(String face) {
return new GraphicTextTracker(mGraphicOverlay);
}
}
private clreplaced GraphicTextTracker extends Tracker<String> {
private GraphicOverlay mOverlay;
private TextGraphic mTextGraphic;
GraphicTextTracker(GraphicOverlay overlay) {
mOverlay = overlay;
mTextGraphic = new TextGraphic(overlay);
}
public void onUpdate() {
mOverlay.add(mTextGraphic);
mTextGraphic.updateText(3);
}
@Override
public void onDone() {
mOverlay.remove(mTextGraphic);
}
}
// ==============================================================================================
// Graphic Face Tracker
// ==============================================================================================
/**
* Factory for creating a face tracker to be replacedociated with a new face. The multiprocessor
* uses this factory to create face trackers as needed -- one for each individual.
*/
private clreplaced GraphicFaceTrackerFactory implements MultiProcessor.Factory<Face> {
@Override
public Tracker<Face> create(Face face) {
return new GraphicFaceTracker(mGraphicOverlay);
}
}
/**
* Face tracker for each detected individual. This maintains a face graphic within the app's
* replacedociated face overlay.
*/
private clreplaced GraphicFaceTracker extends Tracker<Face> {
private GraphicOverlay mOverlay;
private FaceGraphic mFaceGraphic;
GraphicFaceTracker(GraphicOverlay overlay) {
mOverlay = overlay;
mFaceGraphic = new FaceGraphic(overlay, typeFace);
}
/**
* Start tracking the detected face instance within the face overlay.
*/
@Override
public void onNewItem(int faceId, Face item) {
mFaceGraphic.setId(faceId);
}
/**
* Update the position/characteristics of the face within the overlay.
*/
@Override
public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) {
mOverlay.add(mFaceGraphic);
mFaceGraphic.updateFace(face, typeFace);
}
/**
* Hide the graphic when the corresponding face was not detected. This can happen for
* intermediate frames temporarily (e.g., if the face was momentarily blocked from
* view).
*/
@Override
public void onMissing(FaceDetector.Detections<Face> detectionResults) {
mOverlay.remove(mFaceGraphic);
}
/**
* Called when the face is replacedumed to be gone for good. Remove the graphic annotation from
* the overlay.
*/
@Override
public void onDone() {
mOverlay.remove(mFaceGraphic);
}
}
}
16
Source : JazzyViewPager.java
with Apache License 2.0
from Demidong
with Apache License 2.0
from Demidong
public clreplaced JazzyViewPager extends ViewPager {
public static final String TAG = "JazzyViewPager";
float x = 0, y = 0;
private boolean mEnabled = true;
private boolean mFadeEnabled = false;
private boolean mOutlineEnabled = false;
public static int sOutlineColor = Color.WHITE;
private TransitionEffect mEffect = TransitionEffect.Standard;
private HashMap<Integer, Object> mObjs = new LinkedHashMap<Integer, Object>();
private static final float SCALE_MAX = 0.5f;
private static final float ZOOM_MAX = 0.5f;
private static final float ROT_MAX = 15.0f;
public enum TransitionEffect {
Standard,
Tablet,
CubeIn,
CubeOut,
FlipVertical,
FlipHorizontal,
Stack,
ZoomIn,
ZoomOut,
RotateUp,
RotateDown,
Accordion
}
private static final boolean API_11;
static {
API_11 = Build.VERSION.SDK_INT >= 11;
}
public JazzyViewPager(Context context) {
this(context, null);
}
/**
* 获得所有的自定义的样式
*
* @param context
* @param attrs
*/
@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 void setFadeEnabled(boolean enabled) {
mFadeEnabled = enabled;
}
public boolean getFadeEnabled() {
return mFadeEnabled;
}
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);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return mEnabled ? super.onInterceptTouchEvent(arg0) : false;
}
private State mState;
private int oldPage;
private View mLeft;
private View mRight;
private float mRot;
private float mTrans;
private float mScale;
private enum State {
IDLE, GOING_LEFT, GOING_RIGHT
}
// public void reset() {
// resetPrivate();
// int curr = getCurrenreplacedem();
// 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);
// }
// }
private void logState(View v, String replacedle) {
Log.v(TAG, replacedle + ": 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 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 animateCubeIn(View left, View right, float positionOffset) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = 90.0f * positionOffset;
Log.e(TAG, "left.getMeasuredWidth()= " + left.getMeasuredWidth() + " ,left.getMeasuredHeight() = " + left.getMeasuredHeight());
ViewHelper.setPivotX(left, left.getMeasuredWidth());
ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
ViewHelper.setScaleX(left, 1 - positionOffset);
ViewHelper.setScaleY(left, 1 - positionOffset);
ViewHelper.setRotationY(left, mRot);
}
if (right != null) {
manageLayer(right, true);
mRot = -90.0f * (1 - positionOffset);
Log.e(TAG, "right.getMeasuredWidth()= " + right.getMeasuredWidth() + " ,right.getMeasuredHeight() = " + right.getMeasuredHeight());
ViewHelper.setPivotX(right, 0);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
ViewHelper.setScaleX(right, positionOffset);
ViewHelper.setScaleY(right, positionOffset);
ViewHelper.setRotationY(right, mRot);
}
}
}
private void animateCubeOut(View left, View right, float positionOffset) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = -70.0f * positionOffset;
ViewHelper.setPivotX(left, left.getMeasuredWidth());
ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
// ViewHelper.setScaleX(left,1 - positionOffset);
// ViewHelper.setScaleY(left,1 - positionOffset);
ViewHelper.setRotationY(left, mRot);
}
if (right != null) {
manageLayer(right, true);
mRot = 70.0f * (1 - positionOffset);
ViewHelper.setPivotX(right, 0);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
// ViewHelper.setScaleX(right,positionOffset);
// ViewHelper.setScaleY(right,positionOffset);
ViewHelper.setRotationY(right, mRot);
}
}
}
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());
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, 0);
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);
}
}
private Matrix mMatrix = new Matrix();
private Camera mCamera = new Camera();
private float[] mTempFloat2 = new float[2];
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) {
// Log.e(TAG, "position= " + position + " ,positionOffset = "
// + positionOffset + ",positionOffsetPixels = "
// + positionOffsetPixels);
if (mState == State.IDLE && positionOffset > 0) {
oldPage = getCurrenreplacedem();
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:
// animateScroll(position,effectOffset);
break;
case Tablet:
animateTablet(mLeft, mRight, effectOffset);
break;
case CubeIn:
animateCubeIn(mLeft, mRight, effectOffset);
break;
case CubeOut:
animateCubeOut(mLeft, mRight, effectOffset);
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;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch(ev.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
x = ev.getX();
y = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(ev.getX() - x) > Math.abs(ev.getY() - y)) {
getParent().requestDisallowInterceptTouchEvent(true);
} else {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return super.onTouchEvent(ev);
}
}
16
Source : RotateView.java
with Apache License 2.0
from CoderLengary
with Apache License 2.0
from CoderLengary
/**
* Created by CoderLengary
*/
public clreplaced RotateView extends android.support.v7.widget.AppCompatImageView {
private int canvasDegree;
public int getCanvasDegree() {
return canvasDegree;
}
public void setCanvasDegree(int canvasDegree) {
this.canvasDegree = canvasDegree;
invalidate();
}
public int getLeftCameraDegree() {
return leftCameraDegree;
}
public void setLeftCameraDegree(int leftCameraDegree) {
this.leftCameraDegree = leftCameraDegree;
invalidate();
}
public int getRightCameraDegree() {
return rightCameraDegree;
}
public void setRightCameraDegree(int rightCameraDegree) {
this.rightCameraDegree = rightCameraDegree;
invalidate();
}
private int leftCameraDegree;
private int rightCameraDegree;
private Bitmap bitmap;
Paint paint;
Camera camera;
private int bitmapWidth;
private int bitmapHeight;
AnimatorSet animatorSet;
public RotateView(Context context) {
super(context);
}
public RotateView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RotateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RotateView);
BitmapDrawable bitmapDrawable = (BitmapDrawable) array.getDrawable(R.styleable.RotateView_viewBackgound2);
array.recycle();
if (bitmapDrawable != null) {
bitmap = bitmapDrawable.getBitmap();
byte[] bytes = BitmapUtil.bitmap2Bytes(bitmap);
bitmap = BitmapUtil.resizeBitmapBytes(bytes);
} else {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
}
camera = new Camera();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
DisplayMetrics metrics = getResources().getDisplayMetrics();
float newZ = -metrics.density * 6;
camera.setLocation(0, 0, newZ);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ObjectAnimator rotateAnimator = ObjectAnimator.ofInt(this, "canvasDegree", 0, 270);
ObjectAnimator leftCameraAnimator = ObjectAnimator.ofInt(this, "leftCameraDegree", 0, 45);
ObjectAnimator rightCameraAnimator = ObjectAnimator.ofInt(this, "rightCameraDegree", 0, -45);
rotateAnimator.setDuration(2000);
leftCameraAnimator.setDuration(1000);
rightCameraAnimator.setDuration(1000);
animatorSet = new AnimatorSet();
animatorSet.playSequentially(rightCameraAnimator, rotateAnimator, leftCameraAnimator);
animatorSet.start();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
animatorSet.cancel();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
bitmapWidth = bitmap.getWidth();
bitmapHeight = bitmap.getHeight();
int x = width / 2 - bitmapWidth / 2;
int y = height / 2 - bitmapHeight / 2;
// 右半部分绘制
camera.save();
canvas.save();
canvas.translate(width / 2, height / 2);
canvas.rotate(-canvasDegree);
camera.rotateY(rightCameraDegree);
camera.applyToCanvas(canvas);
canvas.clipRect(0, -height, width, height);
canvas.rotate(canvasDegree);
canvas.translate(-width / 2, -height / 2);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
camera.restore();
// 左半部分绘制
camera.save();
canvas.save();
canvas.translate(width / 2, height / 2);
canvas.rotate(-canvasDegree);
camera.rotateY(leftCameraDegree);
camera.applyToCanvas(canvas);
canvas.clipRect(-width, -height, 0, height);
canvas.rotate(canvasDegree);
canvas.translate(-width / 2, -height / 2);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
camera.restore();
}
}
16
Source : DashView.java
with Apache License 2.0
from aohanyao
with Apache License 2.0
from aohanyao
/**
* Created by 江俊超 on 2018/11/3.
* Version:1.0
* Description: 转动的图片
* ChangeLog:
*/
public clreplaced DashView extends View {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final float BITMAP_SIZE = Utils.dp2px(200);
private Camera mCamera;
private Bitmap mBitmap;
private float mCenterY;
private float mCenterX;
private float degrees = 0;
private float degX = 0;
private float degY = 0;
private AnimatorSet animatorSet;
public DashView(Context context) {
super(context);
}
public DashView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DashView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
mBitmap = Utils.getDrawableBitmap(getContext(), R.drawable.icon_android_road, BITMAP_SIZE);
mCamera = new Camera();
mCamera.setLocation(0, 0, -8 * getResources().getDisplayMetrics().density);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mCenterX = BITMAP_SIZE;
mCenterY = BITMAP_SIZE;
// mCenterX = getWidth() / 2 - BITMAP_SIZE / 2;
// mCenterY = getHeight() / 2 - BITMAP_SIZE / 2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(0xffcccccc);
// -------------------------绘制上半部分 start
canvas.save();
// 将原点移动到中心去
canvas.translate(mCenterX, mCenterY);
canvas.rotate(-degrees);
// 进行裁剪,现在是居中了,所以底部就是0,顶部是负数
canvas.clipRect(-BITMAP_SIZE, -BITMAP_SIZE, BITMAP_SIZE, 0);
mCamera.save();
mCamera.rotateX(-degY);
mCamera.applyToCanvas(canvas);
canvas.rotate(degrees);
// 将原点移动回到0.0
canvas.translate(-mCenterX, -mCenterY);
// 绘制 图片
canvas.drawBitmap(mBitmap, mCenterX - BITMAP_SIZE / 2, mCenterY - BITMAP_SIZE / 2, mPaint);
canvas.restore();
mCamera.restore();
// -------------------------绘制上半部分 end
// -------------------------绘制下半部分 start
canvas.save();
// 将原点移动到中心
canvas.translate(mCenterX, mCenterY);
canvas.rotate(-degrees);
// 进行裁剪
canvas.clipRect(-BITMAP_SIZE, 0, BITMAP_SIZE, BITMAP_SIZE);
mCamera.save();
mCamera.rotateX(degX);
mCamera.applyToCanvas(canvas);
canvas.rotate(degrees);
// 将原点移动回到 0,0
canvas.translate(-mCenterX, -mCenterX);
// 绘制bitmap
canvas.drawBitmap(mBitmap, mCenterX - BITMAP_SIZE / 2, mCenterY - BITMAP_SIZE / 2, mPaint);
canvas.restore();
mCamera.restore();
// -------------------------绘制下半部分 end
}
public float getDegrees() {
return degrees;
}
public void setDegrees(float degrees) {
this.degrees = degrees;
postInvalidate();
}
public float getDegX() {
return degX;
}
public void setDegX(float degX) {
this.degX = degX;
postInvalidate();
}
public float getDegY() {
return degY;
}
public void setDegY(float degY) {
this.degY = degY;
postInvalidate();
}
public void start() {
if (animatorSet != null) {
animatorSet.cancel();
animatorSet = null;
}
// 恢复初始状态
setDegrees(0);
setDegX(0);
setDegY(0);
// 先旋转X轴,然后进行转动,最后进行Y轴选准
// 翻页动画
ObjectAnimator degXAnimator = ObjectAnimator.ofFloat(this, "degX", 0, 45);
degXAnimator.setDuration(1200);
// 整个旋转动画
ObjectAnimator degreesAnimator = ObjectAnimator.ofFloat(this, "degrees", 0, 270);
degreesAnimator.setDuration(3000);
ObjectAnimator degYAnimator = ObjectAnimator.ofFloat(this, "degY", 0, 45);
degYAnimator.setDuration(1200);
animatorSet = new AnimatorSet();
animatorSet.playSequentially(degXAnimator, degreesAnimator, degYAnimator);
animatorSet.start();
}
}
16
Source : CameraRotaeView.java
with Apache License 2.0
from aohanyao
with Apache License 2.0
from aohanyao
/**
* Created by 江俊超 on 2018/10/31.
* Version:1.0
* Description: 旋转图
* ChangeLog:
*/
public clreplaced CameraRotaeView extends View {
private final String TAG = "ImageTextView";
/**
* 画笔
*/
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Bitmap mBitmap;
private Camera mCamera;
private float degrees = 20;
private Animator animator;
/**
* 图片的宽度
*/
private final float BITMAP_WIDTH = Utils.dp2px(200);
{
mPaint.setTextSize(Utils.dp2px(20));
mBitmap = Utils.getDrawableBitmap(getContext(), R.drawable.icon_android_road, BITMAP_WIDTH);
mCamera = new Camera();
mCamera.rotateX(45);
mCamera.setLocation(0, 0, -8 * getResources().getDisplayMetrics().density);
}
public CameraRotaeView(Context context) {
super(context);
}
public CameraRotaeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CameraRotaeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
float centerX = BITMAP_WIDTH;
float centerY = BITMAP_WIDTH;
// ----绘制上半部分
canvas.save();
canvas.translate(centerX, centerX);
canvas.rotate(-degrees);
canvas.clipRect(-BITMAP_WIDTH, -BITMAP_WIDTH, BITMAP_WIDTH, 0);
canvas.rotate(degrees);
canvas.translate(-centerX, -centerY);
canvas.drawBitmap(mBitmap, centerX - BITMAP_WIDTH / 2, centerY - BITMAP_WIDTH / 2, mPaint);
canvas.restore();
// 绘制下半部分
canvas.save();
// 其实是把 x0 y0 移动到了中心点
// canvas.translate 移动的是坐标原点,而不是画布
canvas.translate(centerX, centerY);
canvas.rotate(-degrees);
// 然后将重心点移动到原点附近
// if (degrees != 0)
mCamera.applyToCanvas(canvas);
canvas.clipRect(-BITMAP_WIDTH, 0, BITMAP_WIDTH, BITMAP_WIDTH);
canvas.rotate(degrees);
canvas.translate(-centerX, -centerY);
canvas.drawBitmap(mBitmap, centerX - BITMAP_WIDTH / 2, centerY - BITMAP_WIDTH / 2, mPaint);
canvas.restore();
}
public float getDegrees() {
return degrees;
}
public void setDegrees(float degrees) {
this.degrees = degrees;
invalidate();
}
/**
* 应该使用更多的动画来完善
*/
@Deprecated
public void startAmin() {
if (animator != null) {
animator.cancel();
animator = null;
}
animator = ObjectAnimator.ofFloat(this, "degrees", 20, 360);
animator.setDuration(3500);
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
// setDegrees(0);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
}
}
15
Source : ITHomeLoadingView.java
with Apache License 2.0
from zyyoona7
with Apache License 2.0
from zyyoona7
/**
* Created by zyyoona7 on 2017/6/22.
*/
public clreplaced ITHomeLoadingView extends BaseProgressView {
// 画笔
private Paint mPaint;
// 矩阵
private Matrix mMatrix;
// Camera,配合矩阵左各种旋转
private Camera mCamera;
// 字体颜色
private int mFontColor = Color.WHITE;
// 关键字
private String mKeyword = "IT";
// 字体大小
private float mFontSize = 15f;
// 主颜色
private int mHomeColor = DEFAULT_COLOR;
// 测量字体边界的rect
private Rect mRect = null;
// 画圆弧时需要
private RectF mRectF = null;
private float degree;
// 圆环与圆的间距
private float mRingSpacing = DEFAULT_PAINT_WIDTH;
// 圆环宽度
private float mStrokeWidth = DEFAULT_PAINT_WIDTH;
public ITHomeLoadingView(Context context) {
super(context);
}
public ITHomeLoadingView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected int setMaxProgress() {
return 360;
}
@Override
protected void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
// 粗体
mPaint.setFakeBoldText(true);
mPaint.setColor(DEFAULT_COLOR);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(dp2px(mStrokeWidth));
// 测量字体边界
// mRect = new Rect();
mMatrix = new Matrix();
mCamera = new Camera();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float spacing = 10;
float centerX = getWidth() / 2;
float centerY = getHeight() / 2;
// 画实心圆
mPaint.setStrokeWidth(dp2px(mStrokeWidth));
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(centerX, centerX, centerX - dp2px(mStrokeWidth) - spacing - dp2px(mRingSpacing), mPaint);
mPaint.setTextSize(sp2px(mFontSize));
mPaint.setColor(mFontColor);
if (mRect == null) {
mRect = new Rect();
}
mPaint.getTextBounds(mKeyword, 0, mKeyword.length(), mRect);
float textWidth = mPaint.measureText(mKeyword);
// 画文字,居中
canvas.drawText(mKeyword, (getWidth() - textWidth) / 2, (getHeight() - mRect.height()) / 2 + mRect.height(), mPaint);
if (mCurrentMode == MODE_PROGRESS) {
// 下拉过程
mPaint.setColor(mHomeColor);
mPaint.setStyle(Paint.Style.STROKE);
if (mRectF == null) {
// 有边距,否则圆弧会不完全
mRectF = new RectF(spacing, spacing, getWidth() - spacing, getHeight() - spacing);
}
canvas.drawArc(mRectF, 0, mCurrentProgress, false, mPaint);
} else {
// loading过程
// 矩阵+Camera 控制旋转
mMatrix.reset();
mCamera.save();
mCamera.rotateY(degree);
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-centerX, -centerY);
mMatrix.postTranslate(centerX, centerY);
canvas.concat(mMatrix);
mPaint.setColor(mHomeColor);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(centerX, centerX, centerX - spacing, mPaint);
}
}
@Override
public void setColor(int color) {
this.mHomeColor = color;
postInvalidate();
}
/**
* 设置字体颜色
*
* @param color
*/
public void setFontColor(int color) {
this.mFontColor = color;
postInvalidate();
}
/**
* 设置字体大小
*
* @param fontSize
*/
public void setFontSize(float fontSize) {
this.mFontSize = fontSize;
mPaint.setTextSize(mFontSize);
postInvalidate();
}
/**
* 设置绘画文字
*
* @param keyword
*/
public void setKeyword(String keyword) {
mKeyword = keyword;
mPaint.getTextBounds(mKeyword, 0, mKeyword.length(), mRect);
postInvalidate();
}
/**
* 设置圆与圆环之间的间距
*
* @param spacing
*/
public void setRingSpacing(float spacing) {
this.mRingSpacing = spacing;
postInvalidate();
}
/**
* 设置圆环的宽度
*
* @param strokeWidth
*/
public void setStrokeWidth(float strokeWidth) {
this.mStrokeWidth = strokeWidth;
postInvalidate();
}
@Override
public void startAnim() {
stopAnim();
setMode(MODE_ROTATE);
startAnim(0, 180, 500);
}
@Override
public void startAnim(long time) {
stopAnim();
setMode(MODE_ROTATE);
startAnim(0, 180, time);
}
@Override
protected int getRepeatCount() {
return ValueAnimator.INFINITE;
}
@Override
protected int getRepeatMode() {
return ValueAnimator.RESTART;
}
@Override
protected void onAnimatorUpdate(ValueAnimator animator) {
degree = (float) animator.getAnimatedValue();
postInvalidate();
}
}
15
Source : AnimatorProxy.java
with Apache License 2.0
from triline3
with Apache License 2.0
from triline3
/**
* A proxy clreplaced to allow for modifying post-3.0 view properties on all pre-3.0
* platforms. <strong>DO NOT</strong> wrap your views with this clreplaced if you
* are using {@code ObjectAnimator} as it will handle that itself.
*/
public final clreplaced AnimatorProxy extends Animation {
/**
* Whether or not the current running platform needs to be proxied.
*/
public static final boolean NEEDS_PROXY = Integer.valueOf(Build.VERSION.SDK).intValue() < Build.VERSION_CODES.HONEYCOMB;
private static final WeakHashMap<View, AnimatorProxy> PROXIES = new WeakHashMap<View, AnimatorProxy>();
private final WeakReference<View> mView;
private final Camera mCamera = new Camera();
private final RectF mBefore = new RectF();
private final RectF mAfter = new RectF();
private final Matrix mTempMatrix = new Matrix();
private boolean mHasPivot;
private float mAlpha = 1;
private float mPivotX;
private float mPivotY;
private float mRotationX;
private float mRotationY;
private float mRotationZ;
private float mScaleX = 1;
private float mScaleY = 1;
private float mTranslationX;
private float mTranslationY;
private AnimatorProxy(View view) {
// perform transformation immediately
setDuration(0);
// persist transformation beyond duration
setFillAfter(true);
view.setAnimation(this);
mView = new WeakReference<View>(view);
}
/**
* Create a proxy to allow for modifying post-3.0 view properties on all
* pre-3.0 platforms. <strong>DO NOT</strong> wrap your views if you are
* using {@code ObjectAnimator} as it will handle that itself.
*
* @param view View to wrap.
*
* @return Proxy to post-3.0 properties.
*/
public static AnimatorProxy wrap(View view) {
AnimatorProxy proxy = PROXIES.get(view);
// This checks if the proxy already exists and whether it still is the animation of the given view
if (proxy == null || proxy != view.getAnimation()) {
proxy = new AnimatorProxy(view);
PROXIES.put(view, proxy);
}
return proxy;
}
public float getAlpha() {
return mAlpha;
}
public void setAlpha(float alpha) {
if (mAlpha != alpha) {
mAlpha = alpha;
View view = mView.get();
if (view != null) {
view.invalidate();
}
}
}
public float getPivotX() {
return mPivotX;
}
public void setPivotX(float pivotX) {
if (!mHasPivot || mPivotX != pivotX) {
prepareForUpdate();
mHasPivot = true;
mPivotX = pivotX;
invalidateAfterUpdate();
}
}
public float getPivotY() {
return mPivotY;
}
public void setPivotY(float pivotY) {
if (!mHasPivot || mPivotY != pivotY) {
prepareForUpdate();
mHasPivot = true;
mPivotY = pivotY;
invalidateAfterUpdate();
}
}
public float getRotation() {
return mRotationZ;
}
public void setRotation(float rotation) {
if (mRotationZ != rotation) {
prepareForUpdate();
mRotationZ = rotation;
invalidateAfterUpdate();
}
}
public float getRotationX() {
return mRotationX;
}
public void setRotationX(float rotationX) {
if (mRotationX != rotationX) {
prepareForUpdate();
mRotationX = rotationX;
invalidateAfterUpdate();
}
}
public float getRotationY() {
return mRotationY;
}
public void setRotationY(float rotationY) {
if (mRotationY != rotationY) {
prepareForUpdate();
mRotationY = rotationY;
invalidateAfterUpdate();
}
}
public float getScaleX() {
return mScaleX;
}
public void setScaleX(float scaleX) {
if (mScaleX != scaleX) {
prepareForUpdate();
mScaleX = scaleX;
invalidateAfterUpdate();
}
}
public float getScaleY() {
return mScaleY;
}
public void setScaleY(float scaleY) {
if (mScaleY != scaleY) {
prepareForUpdate();
mScaleY = scaleY;
invalidateAfterUpdate();
}
}
public int getScrollX() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getScrollX();
}
public void setScrollX(int value) {
View view = mView.get();
if (view != null) {
view.scrollTo(value, view.getScrollY());
}
}
public int getScrollY() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getScrollY();
}
public void setScrollY(int value) {
View view = mView.get();
if (view != null) {
view.scrollTo(view.getScrollX(), value);
}
}
public float getTranslationX() {
return mTranslationX;
}
public void setTranslationX(float translationX) {
if (mTranslationX != translationX) {
prepareForUpdate();
mTranslationX = translationX;
invalidateAfterUpdate();
}
}
public float getTranslationY() {
return mTranslationY;
}
public void setTranslationY(float translationY) {
if (mTranslationY != translationY) {
prepareForUpdate();
mTranslationY = translationY;
invalidateAfterUpdate();
}
}
public float getX() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getLeft() + mTranslationX;
}
public void setX(float x) {
View view = mView.get();
if (view != null) {
setTranslationX(x - view.getLeft());
}
}
public float getY() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getTop() + mTranslationY;
}
public void setY(float y) {
View view = mView.get();
if (view != null) {
setTranslationY(y - view.getTop());
}
}
private void prepareForUpdate() {
View view = mView.get();
if (view != null) {
computeRect(mBefore, view);
}
}
private void invalidateAfterUpdate() {
View view = mView.get();
if (view == null || view.getParent() == null) {
return;
}
final RectF after = mAfter;
computeRect(after, view);
after.union(mBefore);
((View) view.getParent()).invalidate((int) Math.floor(after.left), (int) Math.floor(after.top), (int) Math.ceil(after.right), (int) Math.ceil(after.bottom));
}
private void computeRect(final RectF r, View view) {
// compute current rectangle according to matrix transformation
final float w = view.getWidth();
final float h = view.getHeight();
// use a rectangle at 0,0 to make sure we don't run into issues with scaling
r.set(0, 0, w, h);
final Matrix m = mTempMatrix;
m.reset();
transformMatrix(m, view);
mTempMatrix.mapRect(r);
r.offset(view.getLeft(), view.getTop());
// Straighten coords if rotations flipped them
if (r.right < r.left) {
final float f = r.right;
r.right = r.left;
r.left = f;
}
if (r.bottom < r.top) {
final float f = r.top;
r.top = r.bottom;
r.bottom = f;
}
}
private void transformMatrix(Matrix m, View view) {
final float w = view.getWidth();
final float h = view.getHeight();
final boolean hasPivot = mHasPivot;
final float pX = hasPivot ? mPivotX : w / 2f;
final float pY = hasPivot ? mPivotY : h / 2f;
final float rX = mRotationX;
final float rY = mRotationY;
final float rZ = mRotationZ;
if ((rX != 0) || (rY != 0) || (rZ != 0)) {
final Camera camera = mCamera;
camera.save();
camera.rotateX(rX);
camera.rotateY(rY);
camera.rotateZ(-rZ);
camera.getMatrix(m);
camera.restore();
m.preTranslate(-pX, -pY);
m.postTranslate(pX, pY);
}
final float sX = mScaleX;
final float sY = mScaleY;
if ((sX != 1.0f) || (sY != 1.0f)) {
m.postScale(sX, sY);
final float sPX = -(pX / w) * ((sX * w) - w);
final float sPY = -(pY / h) * ((sY * h) - h);
m.postTranslate(sPX, sPY);
}
m.postTranslate(mTranslationX, mTranslationY);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
View view = mView.get();
if (view != null) {
t.setAlpha(mAlpha);
transformMatrix(t.getMatrix(), view);
}
}
}
15
Source : TransformView.java
with Apache License 2.0
from REBOOTERS
with Apache License 2.0
from REBOOTERS
/**
* Created by engineer on 2017/9/2.
*/
public clreplaced TransformView extends View {
private static final String TAG = "TransformView";
private Paint mPaint;
private Matrix mMatrix;
private Camera mCamera;
private Paint helpPaint;
//
private Bitmap mBitmap;
//
private Point center;
private int viewW, viewH;
//
private float degreeX, degreeY, degreeZ;
private float scaleX = 1, scaleY = 1;
private boolean isFixed = true;
private boolean UpDownFlipView = true, LeftRightFlipView;
public TransformView(Context context) {
super(context);
init();
}
public TransformView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public TransformView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//
mPaint = new Paint();
mCamera = new Camera();
mMatrix = new Matrix();
initBitmap();
//
helpPaint = new Paint();
helpPaint.setStyle(Paint.Style.STROKE);
}
private void initBitmap() {
if (UpDownFlipView || LeftRightFlipView) {
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cat);
center = new Point((viewW - mBitmap.getWidth()) / 2, (viewH - mBitmap.getHeight()) / 2);
//
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float newZ = -displayMetrics.density * 6;
mCamera.setLocation(0, 0, newZ);
} else {
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android_robot);
center = new Point((viewW - mBitmap.getWidth()) / 2, (viewH - mBitmap.getHeight()) / 2);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCamera.save();
mMatrix.reset();
mCamera.rotateX(degreeX);
mCamera.rotateY(degreeY);
mCamera.rotateZ(degreeZ);
mCamera.getMatrix(mMatrix);
mCamera.restore();
if (isFixed) {
mMatrix.preTranslate(-center.x - mBitmap.getWidth() / 2, -center.y - mBitmap.getHeight() / 2);
mMatrix.postTranslate(center.x + mBitmap.getWidth() / 2, center.y + mBitmap.getHeight() / 2);
}
mMatrix.postScale(scaleX, scaleY, center.x + mBitmap.getWidth() / 2, center.y + mBitmap.getHeight() / 2);
// 上下翻转的FlipView
if (UpDownFlipView) {
canvas.save();
canvas.clipRect(center.x, center.y, center.x + mBitmap.getWidth(), center.y + mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, center.x, center.y, mPaint);
canvas.restore();
canvas.save();
canvas.concat(mMatrix);
canvas.clipRect(center.x, center.y + mBitmap.getHeight() / 2, center.x + mBitmap.getWidth(), center.y + mBitmap.getHeight());
canvas.drawBitmap(mBitmap, center.x, center.y, mPaint);
canvas.restore();
} else if (LeftRightFlipView) {
canvas.save();
canvas.clipRect(center.x + mBitmap.getWidth() / 2, center.y, center.x + mBitmap.getWidth(), center.y + mBitmap.getHeight());
canvas.drawBitmap(mBitmap, center.x, center.y, mPaint);
canvas.restore();
canvas.save();
canvas.concat(mMatrix);
canvas.clipRect(center.x, center.y, center.x + mBitmap.getWidth() / 2, center.y + mBitmap.getHeight());
canvas.drawBitmap(mBitmap, center.x, center.y, mPaint);
canvas.restore();
} else {
canvas.save();
canvas.concat(mMatrix);
canvas.drawBitmap(mBitmap, center.x, center.y, mPaint);
canvas.restore();
}
canvas.drawRect(center.x, center.y, center.x + mBitmap.getWidth(), center.y + mBitmap.getHeight(), helpPaint);
}
public void setDegreeX(float degree) {
this.degreeX = degree;
invalidate();
}
public void setDegreeY(float degree) {
this.degreeY = degree;
invalidate();
}
public void setDegreeZ(float degreeZ) {
this.degreeZ = degreeZ;
invalidate();
}
@Override
public void setScaleX(float scaleX) {
this.scaleX = scaleX;
invalidate();
}
@Override
public void setScaleY(float scaleY) {
this.scaleY = scaleY;
invalidate();
}
public void setFixed(boolean fixed) {
isFixed = fixed;
}
public void setUpDownFlipView(boolean upDownFlipView) {
UpDownFlipView = upDownFlipView;
initBitmap();
invalidate();
}
public void setLeftRightFlipView(boolean leftRightFlipView) {
LeftRightFlipView = leftRightFlipView;
initBitmap();
invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewW = w;
viewH = h;
center = new Point((w - mBitmap.getWidth()) / 2, (h - mBitmap.getHeight()) / 2);
}
}
15
Source : AnimationDrawable.java
with Apache License 2.0
from liuwei1993
with Apache License 2.0
from liuwei1993
/**
* Created by simon on 17-6-5.
*/
public abstract clreplaced AnimationDrawable extends Drawable implements ValueAnimator.AnimatorUpdateListener, Animatable, Drawable.Callback {
private static final Rect ZERO_BOUNDS_RECT = new Rect();
private ValueAnimator animator;
private Camera mCamera;
private Matrix mMatrix;
private float scale = 1;
private float scaleX = 1;
private float scaleY = 1;
private float pivotX;
private float pivotY;
private int animationDelay;
private float rotationX;
private float rotationY;
private float translationX;
private float translationY;
private float rotation;
private float translationXPercentage;
private float translationYPercentage;
@IntRange(from = 0, to = 255)
private int alpha = 255;
protected Rect drawBounds = ZERO_BOUNDS_RECT;
@Override
public int getAlpha() {
return alpha;
}
public AnimationDrawable() {
mCamera = new Camera();
mMatrix = new Matrix();
}
public abstract ValueAnimator createAnimator();
protected abstract void drawSelf(@NonNull Canvas canvas);
@Override
public void draw(@NonNull Canvas canvas) {
float tx = getTranslationX();
tx = tx == 0 ? (int) (getBounds().width() * getTranslationXPercentage()) : tx;
float ty = getTranslationY();
ty = ty == 0 ? (int) (getBounds().height() * getTranslationYPercentage()) : ty;
canvas.translate(tx, ty);
canvas.scale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
canvas.rotate(getRotation(), getPivotX(), getPivotY());
if (getRotationX() != 0 || getRotationY() != 0) {
mCamera.save();
mCamera.rotateX(getRotationX());
mCamera.rotateY(getRotationY());
mCamera.getMatrix(mMatrix);
mMatrix.preTranslate(-getPivotX(), -getPivotY());
mMatrix.postTranslate(getPivotX(), getPivotY());
mCamera.restore();
canvas.concat(mMatrix);
}
drawSelf(canvas);
}
@Override
public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
this.alpha = alpha;
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
// do nothing
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void invalidateDrawable(@NonNull Drawable who) {
invalidateSelf();
}
@Override
public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
scheduleSelf(what, when);
}
@Override
public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
unscheduleSelf(what);
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
final Callback callback = getCallback();
if (callback != null) {
callback.invalidateDrawable(this);
}
}
public void reset() {
scale = 1;
rotationX = 0;
rotationY = 0;
translationX = 0;
translationY = 0;
rotation = 0;
translationXPercentage = 0f;
translationYPercentage = 0f;
}
@Override
public void start() {
animator = createAnimator();
if (animator != null) {
animator.addUpdateListener(this);
animator.setStartDelay(getAnimationDelay());
AnimUtils.start(animator);
}
}
@Override
public void stop() {
AnimUtils.stop(animator);
reset();
if (animator != null) {
animator.removeUpdateListener(this);
animator = null;
}
}
@Override
public boolean isRunning() {
return AnimUtils.isRunning(animator);
}
// getters and setters
public float getScale() {
return scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public float getScaleX() {
return scaleX;
}
public void setScaleX(float scaleX) {
this.scaleX = scaleX;
}
public float getScaleY() {
return scaleY;
}
public void setScaleY(float scaleY) {
this.scaleY = scaleY;
}
public float getPivotX() {
return pivotX;
}
public float getPivotY() {
return pivotY;
}
public int getAnimationDelay() {
return animationDelay;
}
public void setAnimationDelay(int animationDelay) {
this.animationDelay = animationDelay;
}
public float getRotationX() {
return rotationX;
}
public void setRotationX(float rotationX) {
this.rotationX = rotationX;
}
public float getRotationY() {
return rotationY;
}
public void setRotationY(float rotateY) {
this.rotationY = rotateY;
}
public float getTranslationX() {
return translationX;
}
public void setTranslationX(float translationX) {
this.translationX = translationX;
}
public float getTranslationY() {
return translationY;
}
public void setTranslationY(float translationY) {
this.translationY = translationY;
}
public float getRotation() {
return rotation;
}
public void setRotation(float rotate) {
this.rotation = rotate;
}
public float getTranslationXPercentage() {
return translationXPercentage;
}
public void setTranslationXPercentage(float translationXPercentage) {
this.translationXPercentage = translationXPercentage;
}
public float getTranslationYPercentage() {
return translationYPercentage;
}
public void setTranslationYPercentage(float translationYPercentage) {
this.translationYPercentage = translationYPercentage;
}
public void setPivotX(float pivotX) {
this.pivotX = pivotX;
}
public void setPivotY(float pivotY) {
this.pivotY = pivotY;
}
public Rect getDrawBounds() {
return drawBounds;
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
this.setDrawBounds(bounds);
}
public void setDrawBounds(@NonNull Rect drawBounds) {
setDrawBounds(drawBounds.left, drawBounds.top, drawBounds.right, drawBounds.bottom);
}
public void setDrawBounds(int left, int top, int right, int bottom) {
this.drawBounds = new Rect(left, top, right, bottom);
pivotX = drawBounds.centerX();
pivotY = drawBounds.centerY();
}
}
15
Source : Rotate3DAnimation.java
with Apache License 2.0
from InnoFang
with Apache License 2.0
from InnoFang
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
// 调节深度
if (mReverse)
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
else
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
// 绕y轴旋转
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
// 修正失真,主要修改 MPERSP_0 和 MPERSP_1
float[] mValues = new float[9];
// 获取数值
matrix.getValues(mValues);
// 数值修正
mValues[6] = mValues[6] / scale;
// 数值修正
mValues[7] = mValues[7] / scale;
// 重新赋值
matrix.setValues(mValues);
// 调节中心点
matrix.preTranslate(-centerX, -centerY);
matrix.postScale(centerX, centerY);
}
15
Source : PressFrameLayout.java
with MIT License
from CeuiLiSA
with MIT License
from CeuiLiSA
public clreplaced PressFrameLayout extends RelativeLayout {
// 父布局宽度
private int width = 0;
// 父布局高度
private int height = 0;
// 为阴影和按压变形预留位置
private int padding;
// 控件圆角
private int cornerRadius;
// 阴影偏移
private float shadeOffset;
Paint paintBg = new Paint(Paint.ANTI_ALIAS_FLAG);
Camera camera = new Camera();
// 触摸点x轴方向偏移比例
float cameraX = 0f;
// 触摸点y轴方向偏移比例
float cameraY = 0f;
// 背景色
private int colorBg;
// 背景阴影透明度
private int shadeAlpha = 0xaa000000;
// 按压缩放动画控制
private float touchProgress = 1f;
// 相机旋转(按压偏移)动画控制
private float cameraProgress = 0f;
// 按压效果区域
TouchArea pressArea = new TouchArea(0, 0, 0, 0);
// 按压位置是在内圈还是外圈
boolean isInPressArea = true;
// 倾斜时的相机最大倾斜角度,deg
private int maxAngle = 5;
// 整体按压时的形变控制
private float scale = 0.98f;
// 计算按压时间,小于500毫秒响应onClick()
private long pressTime = 0;
// background为图片时
Bitmap bitmap;
Rect srcRectF = new Rect();
RectF dstRectF = new RectF();
public PressFrameLayout(Context context) {
super(context);
}
public PressFrameLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public PressFrameLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
// 开启viewGroup的onDraw()
setWillNotDraw(false);
padding = new DensityUtil().dip2px(20);
cornerRadius = new DensityUtil().dip2px(5);
shadeOffset = new DensityUtil().dip2px(5);
// View的background为颜色或者图片的两种情况
Drawable background = getBackground();
if (background instanceof ColorDrawable) {
colorBg = ((ColorDrawable) background).getColor();
paintBg.setColor(colorBg);
} else if (background instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) background).getBitmap();
srcRectF = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
}
setBackground(null);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isInPressArea) {
camera.save();
// 相机在控件中心上方,在x,y轴方向旋转,形成控件倾斜效果
camera.rotateX(maxAngle * cameraX * cameraProgress);
camera.rotateY(maxAngle * cameraY * cameraProgress);
canvas.translate(width / 2f, height / 2f);
camera.applyToCanvas(canvas);
// 还原canvas坐标系
canvas.translate(-width / 2f, -height / 2f);
camera.restore();
}
// 绘制阴影和背景
paintBg.setShadowLayer(shadeOffset * touchProgress, 0, 0, (colorBg & 0x00FFFFFF) | shadeAlpha);
if (bitmap != null) {
canvas.drawBitmap(bitmap, srcRectF, dstRectF, paintBg);
} else {
canvas.drawRoundRect(dstRectF, cornerRadius, cornerRadius, paintBg);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
dstRectF.set(padding, padding, width - padding, height - padding);
// 计算输入按压的内部范围,布局中心部分为内圈,其他为外圈
pressArea.set((width - 2 * padding) / 4f + padding, (height - 2 * padding) / 4f + padding, width - (width - 2 * padding) / 4f - padding, height - (width - 2 * padding) / 4f - padding);
}
/**
* 判断是按压内圈还是外圈
* @return true:按压内圈;false:按压外圈
*/
private boolean isInPressArea(float x, float y) {
return x > pressArea.getLeft() && x < pressArea.getRight() && y > pressArea.getTop() && y < pressArea.getBottom();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
AnimatorSet animatorSet = new AnimatorSet();
// 按压动画时长
int duration = 100;
int type = 0;
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
pressTime = System.currentTimeMillis();
type = 1;
isInPressArea = isInPressArea(event.getX(), event.getY());
break;
case MotionEvent.ACTION_CANCEL:
type = 2;
break;
case MotionEvent.ACTION_UP:
if ((System.currentTimeMillis() - pressTime) < 500) {
performClick();
}
type = 2;
break;
}
if (isInPressArea) {
// 内圈按压效果
if (type != 0) {
ObjectAnimator animX = ObjectAnimator.ofFloat(this, "scaleX", type == 1 ? 1 : scale, type == 1 ? scale : 1).setDuration(duration);
ObjectAnimator animY = ObjectAnimator.ofFloat(this, "scaleY", type == 1 ? 1 : scale, type == 1 ? scale : 1).setDuration(duration);
ObjectAnimator animZ = ObjectAnimator.ofFloat(this, "touchProgress", type == 1 ? 1 : 0, type == 1 ? 0 : 1).setDuration(duration);
animX.setInterpolator(new DecelerateInterpolator());
animY.setInterpolator(new DecelerateInterpolator());
animZ.setInterpolator(new DecelerateInterpolator());
animatorSet.playTogether(animX, animY, animZ);
animatorSet.start();
}
} else {
// 外圈按压效果
cameraX = (event.getX() - width / 2f) / ((width - 2 * padding) / 2f);
if (cameraX > 1)
cameraX = 1;
if (cameraX < -1)
cameraX = -1;
cameraY = (event.getY() - height / 2f) / ((height - 2 * padding) / 2f);
if (cameraY > 1)
cameraY = 1;
if (cameraY < -1)
cameraY = -1;
// 坐标系调整
float tmp = cameraX;
cameraX = -cameraY;
cameraY = tmp;
switch(type) {
case // 按下动画
1:
ObjectAnimator.ofFloat(this, "cameraProgress", 0, 1).setDuration(duration).start();
break;
case // 还原动画
2:
ObjectAnimator.ofFloat(this, "cameraProgress", 1, 0).setDuration(duration).start();
break;
default:
break;
}
invalidate();
}
return true;
}
public float getTouchProgress() {
return touchProgress;
}
public void setTouchProgress(float touchProgress) {
this.touchProgress = touchProgress;
invalidate();
}
public float getCameraProgress() {
return cameraProgress;
}
public void setCameraProgress(float cameraProgress) {
this.cameraProgress = cameraProgress;
invalidate();
}
@Override
public boolean performClick() {
return super.performClick();
}
}
See More Examples