android 卡片翻转效果的实现

效果图:



实现 :

  一:创建Animator

如图:

第一个卡片要向左翻转消失  ,向右翻转出现

第二张卡片向右翻转消失,向左翻转出现 。

首先第二张向左翻转进入 card_flip_left_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">

    <!--旋转之前,立刻设置透明度alpha为0-->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!--旋转-->
    <objectAnimator
        android:valueFrom="-180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!--旋转中途(时间偏移量取决于startOffset属性)设置透明度为1-->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

card_flip_left_out.xml  第一张向左翻转消失

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 旋转. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!--旋转中途(时间偏移量取决于startOffset属性)设置透明度为0-->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>
card_flip_right_in.xml 第一张向右翻转进入
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--旋转之前,立刻设置透明度alpha为0-->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- 旋转. -->
    <objectAnimator
        android:valueFrom="180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!--旋转中途(时间偏移量取决于startOffset属性)设置透明度为1-->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />

第二向右翻转消失 card_flip_right_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 旋转. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="-180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!--旋转中途(时间偏移量取决于startOffset属性)设置透明度为0-->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>


二.创建View

第一个fragment布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/cardfront"/>
    

</FrameLayout>

第二个fragment 布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
      <ImageView 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/cardback"/>

</FrameLayout>

三 创建Fragment

CardFrontFragment
	@SuppressLint("NewApi")
	public static class CardFrontFragment extends Fragment {

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_cardfront, container,
					false);

		}
	}

CardBackFragment

@SuppressLint("NewApi")
	public static class CardBackFragment extends Fragment {

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_cardback, container,
					false);

		}
	}

四 应用翻转动画  
Activity 的布局 
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    

</FrameLayout>

整体代码

package cardflip;

import com.lt.timesofimagereading.R;

import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager.OnBackStackChangedListener;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.Choreographer.FrameCallback;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationSet;

@SuppressLint("NewApi")
public class CardFlipActivity extends Activity implements
		OnBackStackChangedListener {

	private Handler mHandler = new Handler();

	private boolean mShowingBack = false;

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_card_flip);
		if (savedInstanceState == null) {
			getFragmentManager().beginTransaction()
					.add(R.id.container, new CardFrontFragment()).commit();
		} else {
			mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
		}

	}

	@SuppressLint("NewApi")
	public static class CardFrontFragment extends Fragment {

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_cardfront, container,
					false);

		}
	}

	@SuppressLint("NewApi")
	public static class CardBackFragment extends Fragment {

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_cardback, container,
					false);

		}
	}

	@SuppressLint("NewApi")
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuItem item = menu.add(Menu.NONE, R.id.action_flip, Menu.NONE,
				mShowingBack ? R.string.action_photo : R.string.action_info);
		item.setIcon(mShowingBack ? R.drawable.ic_action_photo
				: R.drawable.ic_action_info);
		item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
		return true;

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case android.R.id.home:
			// Navigate "up" the demo structure to the launchpad activity.
			// See http://developer.android.com/design/patterns/navigation.html
			// for more.
			NavUtils.navigateUpTo(this,
					new Intent(this, CardFlipActivity.class));
			return true;

		case R.id.action_flip:
			flipCard();
			if (mShowingBack) {
				mShowingBack = false;
			}
			return true;
		}
		return super.onOptionsItemSelected(item);

	}

	@SuppressLint("NewApi")
	private void flipCard() {

		// if (mShowingBack) {
		// getFragmentManager().popBackStack();
		// return;
		// }
		Log.e("Acount", getFragmentManager().getBackStackEntryCount() + "");
		if (getFragmentManager().getBackStackEntryCount() == 1) {
			getFragmentManager().popBackStack();
		} else {

			// Flip to the back.

			// mShowingBack = true;

			// Create and commit a new fragment transaction that adds the
			// fragment for the back of
			// the card, uses custom animations, and is part of the fragment
			// manager's back stack.

			getFragmentManager().beginTransaction()

			// Replace the default fragment animations with animator resources
			// representing
			// rotations when switching to the back of the card, as well as
			// animator
			// resources representing rotations when flipping back to the front
			// (e.g. when
			// the system Back button is pressed).
					.setCustomAnimations(R.animator.card_flip_right_in,
							R.animator.card_flip_right_out,
							R.animator.card_flip_left_in,
							R.animator.card_flip_left_out)

					// Replace any fragments currently in the container view
					// with a fragment
					// representing the next page (indicated by the
					// just-incremented currentPage
					// variable).
					.replace(R.id.container, new CardBackFragment())

					// Add this transaction to the back stack, allowing users to
					// press Back
					// to get to the front of the card.
					.addToBackStack(null)

					// Commit the transaction.
					.commit();
		}

		// Defer an invalidation of the options menu (on modern devices, the
		// action bar). This
		// can't be done immediately because the transaction may not yet be
		// committed. Commits
		// are asynchronous in that they are posted to the main thread's message
		// loop.
		mHandler.post(new Runnable() {
			@Override
			public void run() {
				invalidateOptionsMenu();
			}
		});
	}

	@SuppressLint("NewApi")
	@Override
	public void onBackStackChanged() {

		mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);

		// When the back stack changes, invalidate the options menu (action
		// bar).
		invalidateOptionsMenu();
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();

	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值