utilizar reutilizar movil espia descompuesto convertir como cheapcast celular casero camara android api flip nineoldandroids

reutilizar - Mostrando animación de volteo de tarjeta en el viejo android



convertir movil en camara ip (4)

Todos conocemos este article sobre cómo crear animaciones de "card filp" con la new api . Pero, ¿cómo puedo hacer esto on apis < 3.0 ?

Actualizar:

Mientras existan bibliotecas buenas y fáciles de usar como android-FlipView , no creo que de verdad tenga que pasar por formas tan difíciles ...


Encontré la respuesta. Si quieres hacer una animación invertida en ALL ANDROID VERSIONS , usa esto:

Archivo de diseño de la actividad:

<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>

A medida que el archivo de diseño invierte dos grupos de vista, puede poner cualquier otra cosa dentro del grupo de vista y debería funcionar. Ahora veamos los métodos dentro de la actividad que gestiona llamar al código de animación invertida:

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); }

Y finalmente la clase 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); }

Aquí está el enlace para la publicación original: Visualización de animación de volteo de tarjeta en el viejo Android

ACTUALIZACIÓN de @FMMobileFelipeMenezes.

si desea que la animación tenga una escala suave para voltear, cambie esta parte del código a (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);

ACTUALIZACIÓN de @Hesam Hay un buen tutorial que recomiendo leer. Aunque no es tan bueno como el tutorial de Android basado en fragmentos, vale la pena ser leído y útil si desea asignar animaciones a diseños y vistas, así como tenerlo en API antiguas.

Usa la animación de escala de Android para simular un giro en 3D

Proyecto mejorado en github por @LenaBru



Jugué con esto todo el día, y finalmente logré el objetivo final: ¡una carta flotante uniforme como la animación de rotación de dos vistas!

Pongo el proyecto de demostración aquí

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); } }

y llámalo así

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); } } }; }

Estos son los fragmentos

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); } }

y finalmente la vista misma

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>

observe algo del código tomado de las respuestas de Flextra y @FMMobileFelipeMenezes


Utilicé el código de Flextra a continuación, y si desea que la animación tenga una escala suave para voltear, cambie esta parte del código a (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);