在旧的android显示卡翻转animation

我们都知道如何使用new api创build"card filp"animation"card filp" 文章 。 但是我怎样才能使这个on apis < 3.0

更新:

只要有像android-FlipView这样的好的和易于使用的库,我不认为你真的需要经过这么难的方式…

Solutions Collecting From Web of "在旧的android显示卡翻转animation"

find答案。 如果你想在ALL ANDROID VERSIONS上做翻转animation,使用这个:

活动布局文件:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_activity_root" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/transparent" > <RelativeLayout android:id="@+id/main_activity_card_face" android:layout_width="300dp" android:layout_height="407dp" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:background="@drawable/front" android:clickable="true" android:onClick="onCardClick" android:padding="5dp" > </RelativeLayout> <RelativeLayout android:id="@+id/main_activity_card_back" android:layout_width="300dp" android:layout_height="407dp" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:background="@drawable/back" android:clickable="true" android:onClick="onCardClick" android:visibility="gone" > </RelativeLayout> </RelativeLayout> 

当布局文件翻转两个视图组时,您可以将任何其他内容放在视图组中,它应该可以工作。 现在让我们看看处理调用翻转animation代码的活动中的方法:

 public void onCardClick(View view) { flipCard(); } private void flipCard() { View rootLayout = findViewById(R.id.main_activity_root); View cardFace = findViewById(R.id.main_activity_card_face); View cardBack = findViewById(R.id.main_activity_card_back); FlipAnimation flipAnimation = new FlipAnimation(cardFace, cardBack); if (cardFace.getVisibility() == View.GONE) { flipAnimation.reverse(); } rootLayout.startAnimation(flipAnimation); } 

最后是FlipAnimation类:

 public class FlipAnimation extends Animation { private Camera camera; private View fromView; private View toView; private float centerX; private float centerY; private boolean forward = true; /** * Creates a 3D flip animation between two views. * * @param fromView First view in the transition. * @param toView Second view in the transition. */ public FlipAnimation(View fromView, View toView) { this.fromView = fromView; this.toView = toView; setDuration(700); setFillAfter(false); setInterpolator(new AccelerateDecelerateInterpolator()); } 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) { // Angle around the y-axis of the rotation at the given time // calculated both in radians and degrees. final double radians = Math.PI * interpolatedTime; float degrees = (float) (180.0 * radians / Math.PI); // Once we reach the midpoint in the animation, we need to hide the // source view and show the destination view. We also need to change // the angle by 180 degrees so that the destination does not come in // flipped around if (interpolatedTime >= 0.5f) { degrees -= 180.f; fromView.setVisibility(View.GONE); toView.setVisibility(View.VISIBLE); } if (forward) degrees = -degrees; //determines direction of rotation when flip begins final Matrix matrix = t.getMatrix(); camera.save(); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } 

这里是原帖的链接: 在旧的Android上显示卡翻转animation

从@FMMobileFelipeMenezes 更新

如果您想要平滑的缩放animation,请将这部分代码更改为(applyTransformation):

 final Matrix matrix = t.getMatrix(); camera.save(); camera.translate(0, 0, Math.abs(degrees)*2); camera.getMatrix(matrix); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); 

从@Hesam 更新有一个很好的教程,我build议阅读它。 虽然它不如基于片段的Android教程那么好,但是如果要将animation分配给布局和视图以及将其用于旧API,则值得阅读和使用。

使用Android的缩放animation模拟3D翻转

@LenaBru改进了github上的项目

我在下面使用了Flextra代码,如果您想要平滑的缩放比例的animation,请将这部分代码更改为(applyTransformation):

  final Matrix matrix = t.getMatrix(); camera.save(); camera.translate(0, 0, Math.abs(degrees)*2); camera.getMatrix(matrix); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); 

我整天玩这个游戏,终于实现了终极目标 – 像两个视图的旋转animation一样stream畅的卡片翻转!

我把演示项目放在这里

 public class FlipAnimation extends Animation { private Camera camera; private View fromView; private View toView; private float centerX; private float centerY; private boolean forward = true; /** * Creates a 3D flip animation between two views. * * @param fromView * First view in the transition. * @param toView * Second view in the transition. */ public FlipAnimation(View fromView, View toView) { this.fromView = fromView; this.toView = toView; setDuration(1500); setFillAfter(false); // setInterpolator(new AccelerateDecelerateInterpolator()); setInterpolator(new LinearInterpolator()); } public void reverse() { if (forward) { View switchView = toView; toView = fromView; fromView = switchView; } forward = false; } @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) { // Angle around the y-axis of the rotation at the given time // calculated both in radians and degrees. final double radians = Math.PI * interpolatedTime; float degrees = (float) (180.0 * radians / Math.PI); //scale down the views a bit, so that they would look nice when the rotation begins if (interpolatedTime <= 0.05f) { fromView.setScaleX(1 - interpolatedTime); fromView.setScaleY(1 - interpolatedTime); toView.setScaleX(1 - interpolatedTime); toView.setScaleY(1 - interpolatedTime); } // Once we reach the midpoint in the animation, we need to hide the // source view and show the destination view. We also need to change // the angle by 180 degrees so that the destination does not come in //It is very important to call "toView.bringToFront()" and not play with the // visibility of the views, because if you apply this animation more than once, //the subsequent calls may fail if (interpolatedTime >= 0.5f) { degrees -= 180.f; toView.bringToFront(); //these two lines force a layout redraw ((View)toView.getParent()).requestLayout(); ((View)toView.getParent()).invalidate(); } //scale the views back to their original size (Assuming original size was 1) if (interpolatedTime >= 0.95f) { fromView.setScaleX(interpolatedTime); fromView.setScaleY(interpolatedTime); toView.setScaleX(interpolatedTime); toView.setScaleY(interpolatedTime); } if (forward) degrees = -degrees; // determines direction of rotation when flip // begins final Matrix matrix = t.getMatrix(); camera.save(); camera.translate(0, 0, Math.abs(degrees) * 2); camera.getMatrix(matrix); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } } 

并像这样称呼它

 import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.FragmentActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; public class MainActivity extends FragmentActivity { private boolean showingBack; private FragmentLeft left = new FragmentLeft(); private FragmentRight right = new FragmentRight(); private Context context; private Handler handler; private FlipAnimation flipAnimation; private FlipAnimation backFlip; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; handler = new Handler(getMainLooper()); getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, right, "fragmentRight").commit(); getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, left, "fragmentLeft").commit(); findViewById(R.id.flip).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { flipAnimation = new FlipAnimation(left.getView(), right.getView()); backFlip = new FlipAnimation(left.getView(), right.getView()); handler.removeCallbacks(rotate); handler.postDelayed(rotate, 100); } }); } private Runnable rotate = new Runnable() { @Override public void run() { //put a variable showingBack, do not rely on view properties to flip if (!showingBack) { //very important to flip both views, so that when the //left view goes to back and right view goes to front, //the right view finishes the rotation left.getView().startAnimation(flipAnimation); right.getView().startAnimation(flipAnimation); Toast.makeText(context, "flip", Toast.LENGTH_LONG).show(); showingBack = true; } else { showingBack = false; backFlip.reverse(); Toast.makeText(context, "backflip", Toast.LENGTH_LONG).show(); //very important to flip both views, so that when the //right view goes to back and right view goes to front, //the left view finishes the rotation left.getView().startAnimation(backFlip); right.getView().startAnimation(backFlip); } } }; } 

这些是碎片

 import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragmentRight extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_right, container,false); } } import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragmentLeft extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_left, container,false); } } 

最后是观点本身

activity_main.xml中

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="#ff151515" tools:context="com.example.flipviewtest.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <FrameLayout android:id="@+id/fragment_container" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" > </FrameLayout> <Button android:id="@+id/flip" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="flip" /> </RelativeLayout> 

fragment_left.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#ffff0000" > <View android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff0ffff0" android:layout_margin="20dp" /> </LinearLayout> 

fragment_right.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00ff00" android:orientation="vertical" > <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:background="#ff0000ff" /> </LinearLayout> 

注意一些来自Flextra和@FMMobileFelipeMenezes的答案

有好的教程,我build议阅读它。 虽然它不如基于片段的Android教程那么好,但是如果要将animation分配给布局和视图以及将其用于旧API,则值得阅读和使用。

使用Android的缩放animation模拟3D翻转