Создание 3D-флип-анимации в Android с использованием XML
Я создал трехмерный флип из представления с помощью этого руководства для Android
Тем не менее, я сделал это программно, и я хотел бы сделать все это в xml, если это возможно. Я не говорю о простом сокращении взгляда на середину, а затем назад, но в реальном 3D-перевороте.
Возможно ли это через xml?
Ответы
Ответ 1
Вот ответ, хотя он работает только с 3.0 и выше.
1) Создайте новую папку ресурсов под названием "аниматор".
2) Создайте новый XML файл, который я буду называть "flipping". Используйте следующий код xml:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" android:valueTo="360" android:propertyName="rotationY" >
</objectAnimator>
Нет, теги objectAnimator не начинаются с верхнего регистра "O".
3) Запустите анимацию следующим кодом:
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(mContext, R.animator.flipping);
anim.setTarget(A View Object reference goes here i.e. ImageView);
anim.setDuration(3000);
anim.start();
Я получил все это от здесь.
Ответ 2
Поскольку ответы на этот вопрос достаточно датированы, вот более современное решение, основанное на ValueAnimators.
Это решение реализует истинный, визуально привлекательный 3D-флип, потому что он не просто переворачивает представление, но также масштабирует его, пока он переворачивается (это так делает Apple).
Сначала мы устанавливаем ValueAnimator:
mFlipAnimator = ValueAnimator.ofFloat(0f, 1f);
mFlipAnimator.addUpdateListener(new FlipListener(frontView, backView));
И соответствующий прослушиватель обновлений:
public class FlipListener implements ValueAnimator.AnimatorUpdateListener {
private final View mFrontView;
private final View mBackView;
private boolean mFlipped;
public FlipListener(final View front, final View back) {
this.mFrontView = front;
this.mBackView = back;
this.mBackView.setVisibility(View.GONE);
}
@Override
public void onAnimationUpdate(final ValueAnimator animation) {
final float value = animation.getAnimatedFraction();
final float scaleValue = 0.625f + (1.5f * (value - 0.5f) * (value - 0.5f));
if(value <= 0.5f){
this.mFrontView.setRotationY(180 * value);
this.mFrontView.setScaleX(scaleValue);
this.mFrontView.setScaleY(scaleValue);
if(mFlipped){
setStateFlipped(false);
}
} else {
this.mBackView.setRotationY(-180 * (1f- value));
this.mBackView.setScaleX(scaleValue);
this.mBackView.setScaleY(scaleValue);
if(!mFlipped){
setStateFlipped(true);
}
}
}
private void setStateFlipped(boolean flipped) {
mFlipped = flipped;
this.mFrontView.setVisibility(flipped ? View.GONE : View.VISIBLE);
this.mBackView.setVisibility(flipped ? View.VISIBLE : View.GONE);
}
}
Что это!
После этой настройки вы можете перевернуть представления, вызвав
mFlipAnimator.start();
и отмените флип, вызывая
mFlipAnimator.reverse();
Если вы хотите проверить, перевернуто ли представление, реализовать и вызвать эту функцию:
private boolean isFlipped() {
return mFlipAnimator.getAnimatedFraction() == 1;
}
Вы также можете проверить, просматривается ли в настоящее время представление, реализуя этот метод:
private boolean isFlipping() {
final float currentValue = mFlipAnimator.getAnimatedFraction();
return (currentValue < 1 && currentValue > 0);
}
Вы можете комбинировать вышеуказанные функции для реализации хорошей функции для переключения флип, в зависимости от того, перевернута ли она или нет:
private void toggleFlip() {
if(isFlipped()){
mFlipAnimator.reverse();
} else {
mFlipAnimator.start();
}
}
Что это! Простой и легкий. Наслаждайтесь!
Ответ 3
Я создал простую программу для создания флип-представления, например:
![enter image description here]()
В Activity вы должны создать этот метод, чтобы добавить flip_rotation в поле зрения.
private void applyRotation(View view)
{
final Flip3dAnimation rotation = new Flip3dAnimation(view);
rotation.applyPropertiesInRotation();
view.startAnimation(rotation);
}
для этого вам нужно скопировать основной класс, используемый для обеспечения flip_rotation.
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class Flip3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private Camera mCamera;
public Flip3dAnimation(View view) {
mFromDegrees = 0;
mToDegrees = 720;
mCenterX = view.getWidth() / 2.0f;
mCenterY = view.getHeight() / 2.0f;
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
public void applyPropertiesInRotation()
{
this.setDuration(2000);
this.setFillAfter(true);
this.setInterpolator(new AccelerateInterpolator());
}
@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();
Log.e("Degree",""+degrees) ;
Log.e("centerX",""+centerX) ;
Log.e("centerY",""+centerY) ;
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
Ответ 4
Учебник или ссылка om252345 не создают правдоподобных трехмерных переворотов. Простое вращение по оси y не то, что сделано в iOS. Эффект масштабирования также необходим, чтобы создать приятное ощущение флип. Для этого взгляните на этот пример.
Здесь также есть видео .
Ответ 5
Одним из лучших решений для перевода изображения без использования анимации ресурса является следующее: -
ObjectAnimator animation = ObjectAnimator.ofFloat(YOUR_IMAGEVIEW, "rotationY", 0.0f, 360f); // HERE 360 IS THE ANGLE OF ROTATE, YOU CAN USE 90, 180 IN PLACE OF IT, ACCORDING TO YOURS REQUIREMENT
animation.setDuration(500); // HERE 500 IS THE DURATION OF THE ANIMATION, YOU CAN INCREASE OR DECREASE ACCORDING TO YOURS REQUIREMENT
animation.setInterpolator(new AccelerateDecelerateInterpolator());
animation.start();
Ответ 6
-
Самый простой способ сделать это - использовать ViewPropertyAnimator
mImageView.animate().rotationY(360f);
Используя свободный интерфейс, вы можете создавать более сложную и захватывающую анимацию. Например, вы можете включить аппаратное ускорение, просто вызвав метод Layer() (API 16). Больше здесь
-
Если вы хотите выяснить, как создать 3D-анимацию, пожалуйста, следуйте здесь и здесь
-
Я реализовал свое собственное решение только для исследования. Он включает в себя: отмену, ускорение, поддержку API> = 15 и основан на Property Animation. Вся анимация включает в себя 4 части, по 2 на каждую сторону. Каждый objectAnimator имеет прослушиватель, который определяет текущий индекс анимации и представляет изображение в onAnimationStart, а текущее значение времени воспроизведения в onAnimationCancel. Это выглядит как
mQuarterAnim1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mQuarterCurrentAnimStartIndex = QUARTER_ANIM_INDEX_1;
mImageView.setImageResource(mResIdFrontCard);
}
@Override
public void onAnimationCancel(Animator animation) {
mQuarterCurrentAnimPlayTime = ((ObjectAnimator) animation).getCurrentPlayTime();
}
});
Для начала поставь звонок
mAnimatorSet.play(mQuarterAnim1).before(mQuarterAnim2)
Если AnimatorSet был отменен, мы можем вычислить дельту и запустить обратную анимацию, основываясь на текущей индексной анимации и текущем значении времени воспроизведения.
long degreeDelta = mQuarterCurrentAnimPlayTime * QUARTER_ROTATE / QUARTER_ANIM_DURATION;
if (mQuarterCurrentAnimStartIndex == QUARTER_ANIM_INDEX_1) {
mQuarterAnim4.setFloatValues(degreeDelta, QUARTER_FROM_1);
mQuarterAnim4.setDuration(mQuarterCurrentAnimPlayTime);
mAnimatorSet.play(mQuarterAnim4);
}
Полный фрагмент кода вы можете найти здесь
Ответ 7
Добавление к А. Стинбергену великолепного ответа. При перелистывании того же представления (например, при обновлении TextView
) я удалил изменение View.Visibility
в конструкторе, чтобы переход был более плавным.
public FlipListener(final View front, final View back) {
this.mFrontView = front;
this.mBackView = back;
}
Ответ 8
Просто поместите вид, который вы собираетесь анимировать, вместо viewToFlip.
ObjectAnimator flip = ObjectAnimator.ofFloat(viewToFlip, "rotationY", 0f, 360f); // or rotationX
flip.setDuration(2000); // 2 seconds
flip.start();