2016-11-02 82 views
7

Hej faceci, potrzebuję stworzyć animację 3D obracania/obracania w oparciu o prędkość przesunięcia użytkownika na ekranie, udało mi się stworzyć tę animację przy użyciu ObjectAnimator i związanych z nią właściwości, ale potrzebuję sugestii jak możemy stworzyć animację 3D w Androidzie powyżej.Muszę również wykonać niektóre animacje, które są częściowo obracaneStwórz animację 3D dla aplikacji Androidowych

Chociaż dla Androida możemy użyć OPENGL, ale dla prostej animacji OPENGL jest zbyt ciężki, ponieważ nie projektujemy Prawdziwa gra Odsyłam następujące linki:

https://2cupsoftech.wordpress.com/2012/09/18/3d-flip-between-two-view-or-viewgroup-on-android/

http://www.inter-fuser.com/2009/08/android-animations-3d-flip.html

Odpowiedz

2

Spróbuj użyć tego

MainActivity.java

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    ButterKnife.bind(this); 

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    ft.replace(R.id.layout_main, ExampleFragment.newInstance(ExampleFragment.NODIR)); 
    ft.commit(); 
} 

ExampleFragment.java

public class ExampleFragment extends Fragment { 

    @IntDef({NONE, FLIP}) 
    public @interface AnimationStyle {} 
    public static final int NONE  = 0; 
    public static final int FLIP  = 2; 

    @IntDef({NODIR, UP, DOWN, LEFT, RIGHT}) 
    public @interface AnimationDirection {} 
    public static final int NODIR = 0; 
    public static final int UP = 1; 
    public static final int DOWN = 2; 
    public static final int LEFT = 3; 
    public static final int RIGHT = 4; 

    private static final long DURATION = 500; 

    @AnimationStyle 
    private static int sAnimationStyle = FLIP; 

    public static ExampleFragment newInstance(@AnimationDirection int direction) { 
     ExampleFragment f = new ExampleFragment(); 
     f.setArguments(new Bundle()); 
     f.getArguments().putInt("direction", direction); 
     return f; 
    } 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.content_anim, null); 

     // For generating random Colors 
     int color = Color.rgb((int) Math.floor(Math.random() * 128) + 64, 
       (int) Math.floor(Math.random() * 128) + 64, 
       (int) Math.floor(Math.random() * 128) + 64); 
     view.setBackgroundColor(color); 

     ButterKnife.bind(this, view); 
     return view; 
    } 


@Override 
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { 
    switch (sAnimationStyle) { 
     case FLIP: 
      switch (getArguments().getInt("direction")) { 
       case UP: 
        return FlipAnimation.create(FlipAnimation.UP, enter, DURATION); 
       case DOWN: 
        return FlipAnimation.create(FlipAnimation.DOWN, enter, DURATION); 
       case LEFT: 
        return FlipAnimation.create(FlipAnimation.LEFT, enter, DURATION); 
       case RIGHT: 
        return FlipAnimation.create(FlipAnimation.RIGHT, enter, DURATION); 
      } 
      break; 
    } 
    return null; 
} 


    @OnClick(R.id.buttonUp) 
    void onButtonUp() { 
     getArguments().putInt("direction", UP); 
     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.layout_main, ExampleFragment.newInstance(UP)); 
     ft.commit(); 
    } 

    @OnClick(R.id.buttonDown) 
    void onButtonDown() { 
     getArguments().putInt("direction", DOWN); 
     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.layout_main, ExampleFragment.newInstance(DOWN)); 
     ft.commit(); 
    } 

    @OnClick(R.id.buttonLeft) 
    void onButtonLeft() { 
     getArguments().putInt("direction", LEFT); 
     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.layout_main, ExampleFragment.newInstance(LEFT)); 
     ft.commit(); 
    } 

    @OnClick(R.id.buttonRight) 
    void onButtonRight() { 
     getArguments().putInt("direction", RIGHT); 
     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.layout_main, ExampleFragment.newInstance(RIGHT)); 
     ft.commit(); 
    } 
} 

FlipAnimation.java

public class FlipAnimation extends ViewPropertyAnimation { 

    @IntDef({UP, DOWN, LEFT, RIGHT}) 
    @interface Direction {} 
    public static final int UP = 1; 
    public static final int DOWN = 2; 
    public static final int LEFT = 3; 
    public static final int RIGHT = 4; 

    protected final @Direction int mDirection; 
    protected final boolean mEnter; 

    public static FlipAnimation create(@Direction int direction, boolean enter, long duration) { 
     switch (direction) { 
      case UP: 
      case DOWN: 
       return new VerticalFlipAnimation(direction, enter, duration); 
      case LEFT: 
      case RIGHT: 
       return new HorizontalFlipAnimation(direction, enter, duration); 
     } 
     return null; 
    } 

    private FlipAnimation(@Direction int direction, boolean enter, long duration) { 
     mDirection = direction; 
     mEnter = enter; 
     setDuration(duration); 
    } 

    private static class VerticalFlipAnimation extends FlipAnimation { 

     public VerticalFlipAnimation(@Direction int direction, boolean enter, long duration) { 
      super(direction, enter, duration); 
     } 

     @Override 
     public void initialize(int width, int height, int parentWidth, int parentHeight) { 
      super.initialize(width, height, parentWidth, parentHeight); 
      mPivotX = width * 0.5f; 
      mPivotY = (mEnter == (mDirection == UP)) ? 0.0f : height; 
      mCameraZ = -height * 0.015f; 
     } 

     @Override 
     protected void applyTransformation(float interpolatedTime, Transformation t) { 
      float value = mEnter ? (interpolatedTime - 1.0f) : interpolatedTime; 
      if (mDirection == DOWN) value *= -1.0f; 
      mRotationX = value * 180.0f; 
      mTranslationY = -value * mHeight; 

      super.applyTransformation(interpolatedTime, t); 

      // Hide exiting view after half point. 
      if (interpolatedTime >= 0.5f && !mEnter) { 
       mAlpha = 0.0f; 
      } 
      applyTransformation(t); 
     } 
    } 

    private static class HorizontalFlipAnimation extends FlipAnimation { 

     public HorizontalFlipAnimation(@Direction int direction, boolean enter, long duration) { 
      super(direction, enter, duration); 
     } 

     @Override 
     public void initialize(int width, int height, int parentWidth, int parentHeight) { 
      super.initialize(width, height, parentWidth, parentHeight); 
      mPivotX = (mEnter == (mDirection == LEFT)) ? 0.0f : width; 
      mPivotY = height * 0.5f; 
      mCameraZ = -width * 0.015f; 
     } 

     @Override 
     protected void applyTransformation(float interpolatedTime, Transformation t) { 
      float value = mEnter ? (interpolatedTime - 1.0f) : interpolatedTime; 
      if (mDirection == RIGHT) value *= -1.0f; 
      mRotationY = -value * 180.0f; 
      mTranslationX = -value * mWidth; 

      super.applyTransformation(interpolatedTime, t); 

      // Hide exiting view after half point. 
      if (interpolatedTime >= 0.5f && !mEnter) { 
       mAlpha = 0.0f; 
      } 
      applyTransformation(t); 
     } 
    } 
} 

ViewPropertyAnimation.java

public class ViewPropertyAnimation extends Animation { 

    private final Camera mCamera = new Camera(); 
    protected int mWidth = 0; 
    protected int mHeight = 0; 
    protected float mAlpha = 1.0f; 
    protected float mPivotX = 0.0f; 
    protected float mPivotY = 0.0f; 
    protected float mScaleX = 1.0f; 
    protected float mScaleY = 1.0f; 
    protected float mRotationX = 0.0f; 
    protected float mRotationY = 0.0f; 
    protected float mRotationZ = 0.0f; 
    protected float mTranslationX = 0.0f; 
    protected float mTranslationY = 0.0f; 
    protected float mTranslationZ = 0.0f; 
    protected float mCameraX = 0.0f; 
    protected float mCameraY = 0.0f; 
    protected float mCameraZ = -8.0f; 

    private float mFromAlpha = -1.0f; 
    private float mToAlpha = -1.0f; 

    public ViewPropertyAnimation fading(@FloatRange(from=0.0f,to=1.0f) float fromAlpha, @FloatRange(from=0.0f,to=1.0f) float toAlpha) { 
     mFromAlpha = fromAlpha; 
     mToAlpha = toAlpha; 
     return this; 
    } 

    @Override 
    public void initialize(int width, int height, int parentWidth, int parentHeight) { 
     super.initialize(width, height, parentWidth, parentHeight); 
     mWidth = width; 
     mHeight = height; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     super.applyTransformation(interpolatedTime, t); 
     if (mFromAlpha >= 0 && mToAlpha >= 0) { 
      mAlpha = mFromAlpha + (mToAlpha - mFromAlpha) * interpolatedTime; 
     } 
    } 

    protected void applyTransformation(Transformation t) { 
     final Matrix m = t.getMatrix(); 
     final float w = mWidth; 
     final float h = mHeight; 
     final float pX = mPivotX; 
     final float pY = mPivotY; 

     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(); 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { 
       camera.setLocation(mCameraX, mCameraY, mCameraZ); 
      } 
      if (mTranslationZ != 0) { 
       camera.translate(0, 0, mTranslationZ); 
      } 
      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); 

     t.setAlpha(mAlpha); 
    } 
} 
+0

Potrzebuję go obrócić z centrum, a gdy jego 90 * musi mieć grubość –

+0

Chcesz tego samego efektu, jaki podałeś w swoim [pytaniu] (http://www.inter-fuser.com/ 2009/08/android-animations-3d-flip.html)? – MashukKhan

+0

Tak, filp/obrót musi wystąpić od środka (udało mi się), ale nie ma efektu 3D –

1

Faktycznie, trzeba wymienić to:

3D Flip/obracanie animację opartą na szybkości bezstykowa użytkownika na ekranie

Uważam, że Android Animation nie pasuje do twoich sytuacji. Ale jeśli masz doświadczenie w niestandardowym widoku, pomoże ci klasa z Android.graphics.Camera.

Na początku trzeba zadeklarować

camera = new Camera(); 

następnie zastąpić OnDraw.

canvas.save(); 
Matrix matrix = new Matrix(); 
camera.save(); 
camera.rotateY(rotateAngle); 
camera.getMatrix(matrix); 
camera.restore(); 

mPaint.setColor(textBackgroundColor); 
int centerX = diameter/2; 
int centerY = diameter/2; 
matrix.preTranslate(-centerX, -centerY); 
matrix.postTranslate(centerX, centerY); 
canvas.concat(matrix); 
canvas.drawCircle(diameter/2, diameter/2, diameter/2, mPaint); 
canvas.restore(); 

Teraz widać, że obraca się okrąg rotateAngle stopni wokół y axis.And można zmienić wartość rotateAngle dostosować kąt.

Możesz bezpłatnie odsyłać mój ostatni artykuł: here, a kod źródłowy to github link.