私たちはすべてこれを知っています 記事 作成方法"card filp"
を使用したアニメーションnew api
。しかし、どうすればこれを作成できますかon apis < 3.0
?
更新:
Android-FlipView のような使いやすい優れたライブラリがある限り、このような難しい方法を実際に実行する必要はないと思います...
答えが見つかりました。 ALL Android VERSIONS
でフリップアニメーションを実行する場合は、次のようにします。
アクティビティレイアウトファイル:
<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>
レイアウトファイルが2つのビューグループを反転するので、ビューグループ内に他のものを置くことができ、それが機能するはずです。次に、フリップアニメーションコードの呼び出しを処理するアクティビティ内のメソッドを見てみましょう。
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でのカードフリップアニメーションの表示
[〜#〜] update [〜#〜]@FMMobileFelipeMenezesから。
スムーズスケールのアニメーションを反転させる場合は、コードのこの部分を(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);
[〜#〜] update [〜#〜]@Hesamから読むことをお勧めする良いチュートリアルがあります。 Androidチュートリアルほど素敵ではありませんが、レイアウトやビューにアニメーションを割り当てたり、古いAPIでアニメーションを使用したりする場合に役立ちます。
以下のFlextraコードを使用しました。スムーズスケールのアニメーションを反転させたい場合は、コードのこの部分を(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);
私はこれを一日中遊んで、最終的に究極の目標を達成しました-2つのビューの回転アニメーションのようなスムーズなカードフリップ!
私はデモプロジェクトを入れました ここ
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の回答から取得したコードの一部に注意してください
私がそれを読むことを勧める良いチュートリアルがあります。 Androidチュートリアルほど素敵ではありませんが、レイアウトやビューにアニメーションを割り当てたり、古いAPIでアニメーションを使用したりする場合に役立ちます。