this Android tutorial を使用してビューの3Dフリップを作成しました。ただし、プログラムでそれを実行しました。可能な場合はすべてxmlで実行したいと思います。ビューを真ん中に縮小してから元に戻すことではなく、実際の3Dフリップです。
これはxmlで可能ですか?
答えは次のとおりですが、3.0以上でのみ機能します。
1)「animator」という名前の新しいリソースフォルダーを作成します。
2)「flipping」と呼ぶ新しい.xmlファイルを作成します。次の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();
これはすべて here から取得しました。
この質問に対する回答はかなり古いため、ここでは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);
}
上記の関数を組み合わせて、反転するかどうかに応じて、反転を切り替えるNice関数を実装できます。
private void toggleFlip() {
if(isFlipped()){
mFlipAnimator.reverse();
} else {
mFlipAnimator.start();
}
}
それでおしまい!シンプルで簡単。楽しい!
次のようなビューのフリップを作成するための簡単なプログラムを作成しました。
アクティビティで、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);
}
}
リソースアニメーションを使用せずに画像を反転させるより良い解決策の1つは次のとおりです-
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();
最も簡単な方法は、 ViewPropertyAnimator を使用することです
mImageView.animate().rotationY(360f);
流れるようなインターフェイスを使用すると、より複雑でエキサイティングなアニメーションを構築できます。例えば。 withLayer()メソッド(API 16)を呼び出すだけでハードウェアアクセラレーションを有効にできます。もっと こちら
私は研究のためだけに自分の解決策を提案しました。これには、キャンセル、加速、サポート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);
}
あなたが見つけることができる完全なコードスニペット here
ViewToFlipの代わりに、アニメーション化するビューを配置します。
ObjectAnimator flip = ObjectAnimator.ofFloat(viewToFlip, "rotationY", 0f, 360f); // or rotationX
flip.setDuration(2000); // 2 seconds
flip.start();
A. Steenbergenのすばらしい答えに追加します。同じビューを反転するとき(たとえばTextView
を更新するとき)、私はView.Visibility
遷移をよりスムーズに保つために、コンストラクターを変更します。
public FlipListener(final View front, final View back) {
this.mFrontView = front;
this.mBackView = back;
}