亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android 3D旋轉動畫效果實現分解

2020-04-11 12:07:26
字體:
來源:轉載
供稿:網友
這篇文章主要介紹一下如何實現View的3D旋轉效果,實現的主要原理就是圍繞Y軸旋轉,同時在Z軸方面上有一個深入的縮放。

演示的demo主要有以下幾個重點:
1,自定義旋轉動畫
2,動畫做完后,重置ImageView
先看一下程序的運行效果:
 
1,自定義動畫類
這里實現了一個Rotate3dAnimation的類,它擴展了Animation類,重寫applyTransformation()方法,提供指定時間的矩陣變換,我們在這個方法里,就可以利用Camera類得得到一個圍繞Y軸旋轉的matrix,把這個matrix設置到Transformation對象中。 具體的實現代碼如下:
復制代碼 代碼如下:

@Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}

2,如何使用這個動畫類
在Activity中,我們有兩個大小一樣的ImageView,它們都放在FrameLayout中,這樣他們位置是重疊的,對最上面的ImageView做動畫(旋轉角度從0到90),當動畫做完后,再對后面的ImageView做動畫(旋轉角度從90到180),在這里,要控制相應的ImageView隱藏或顯示。
動畫的listener實現如下:
復制代碼 代碼如下:

private final class DisplayNextView implements Animation.AnimationListener {
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
mContainer.post(new SwapViews());
}
public void onAnimationRepeat(Animation animation) {
}
}

動畫做完后,執行的代碼如下:
復制代碼 代碼如下:

private final class SwapViews implements Runnable
{
@Override
public void run()
{
mImageView1.setVisibility(View.GONE);
mImageView2.setVisibility(View.GONE);
mIndex++;
if (0 == mIndex % 2)
{
mStartAnimView = mImageView1;
}
else
{
mStartAnimView = mImageView2;
}
mStartAnimView.setVisibility(View.VISIBLE);
mStartAnimView.requestFocus();
Rotate3dAnimation rotation = new Rotate3dAnimation(
-90,
0,
mCenterX,
mCenterY, mDepthZ, false);
rotation.setDuration(mDuration);
rotation.setFillAfter(true);
rotation.setInterpolator(new DecelerateInterpolator());
mStartAnimView.startAnimation(rotation);
}
}

點擊Button的事件處理實現:
復制代碼 代碼如下:

@Override
public void onClick(View v)
{
mCenterX = mContainer.getWidth() / 2;
mCenterY = mContainer.getHeight() / 2;
getDepthZ();
applyRotation(mStartAnimView, 0, 90);
}

applyRotation的實現如下:
復制代碼 代碼如下:

private void applyRotation(View animView, float startAngle, float toAngle)
{
float centerX = mCenterX;
float centerY = mCenterY;
Rotate3dAnimation rotation = new Rotate3dAnimation(
startAngle, toAngle, centerX, centerY, mDepthZ, true);
rotation.setDuration(mDuration);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView());
animView.startAnimation(rotation);
}

3,完整代碼如下
Rotate3dAnimActivity.java
復制代碼 代碼如下:

public class Rotate3dAnimActivity extends Activity
{
ImageView mImageView1 = null;
ImageView mImageView2 = null;
ImageView mStartAnimView = null;
View mContainer = null;
int mDuration = 500;
float mCenterX = 0.0f;
float mCenterY = 0.0f;
float mDepthZ = 0.0f;
int mIndex = 0;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.rotate_anim);
mImageView1 = (ImageView) findViewById(R.id.imageView1);
mImageView2 = (ImageView) findViewById(R.id.imageView2);
mContainer = findViewById(R.id.container);
mStartAnimView = mImageView1;
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mCenterX = mContainer.getWidth() / 2;
mCenterY = mContainer.getHeight() / 2;
getDepthZ();
applyRotation(mStartAnimView, 0, 90);
}
});
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
private void getDepthZ()
{
EditText editText = (EditText) findViewById(R.id.edit_depthz);
String string = editText.getText().toString();
try
{
mDepthZ = (float)Integer.parseInt(string);
//mDepthZ = Math.min(mDepthZ, 300.0f);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void applyRotation(View animView, float startAngle, float toAngle)
{
float centerX = mCenterX;
float centerY = mCenterY;
Rotate3dAnimation rotation = new Rotate3dAnimation(
startAngle, toAngle, centerX, centerY, mDepthZ, true);
rotation.setDuration(mDuration);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView());
animView.startAnimation(rotation);
}
/**
* This class listens for the end of the first half of the animation.
* It then posts a new action that effectively swaps the views when the container
* is rotated 90 degrees and thus invisible.
*/
private final class DisplayNextView implements Animation.AnimationListener {
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
mContainer.post(new SwapViews());
}
public void onAnimationRepeat(Animation animation) {
}
}
private final class SwapViews implements Runnable
{
@Override
public void run()
{
mImageView1.setVisibility(View.GONE);
mImageView2.setVisibility(View.GONE);
mIndex++;
if (0 == mIndex % 2)
{
mStartAnimView = mImageView1;
}
else
{
mStartAnimView = mImageView2;
}
mStartAnimView.setVisibility(View.VISIBLE);
mStartAnimView.requestFocus();
Rotate3dAnimation rotation = new Rotate3dAnimation(
-90,
0,
mCenterX,
mCenterY, mDepthZ, false);
rotation.setDuration(mDuration);
rotation.setFillAfter(true);
rotation.setInterpolator(new DecelerateInterpolator());
mStartAnimView.startAnimation(rotation);
}
}
}

rotate_anim.xml
復制代碼 代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Do 3d animation" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20px"
android:text="Input Depth on Z axis. [0, 300]"
/>
<EditText
android:id="@+id/edit_depthz"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="0"/>
<FrameLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageView1"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_margin="20dp"
android:src="@drawable/f" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_margin="20dp"
android:src="@drawable/s"
android:visibility="gone"/>
</FrameLayout>
</LinearLayout>

Rotate3dAnimation.java
復制代碼 代碼如下:

package com.nj1s.lib.anim;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;
/**
* An animation that rotates the view on the Y axis between two specified angles.
* This animation also adds a translation on the Z axis (depth) to improve the effect.
*/
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees,
float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}

各位,請想一想,為實現applyTransformation方法時,最后的為什么要有這兩句話:
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲aa在线观看| 最近2019年好看中文字幕视频| 日韩欧美福利视频| 在线精品国产成人综合| 国产精品美腿一区在线看| 日韩性xxxx爱| 国产在线视频2019最新视频| 91精品国产综合久久香蕉| 久久精品亚洲精品| 91久久精品国产91性色| 91精品在线观看视频| 成人情趣片在线观看免费| 成人福利视频在线观看| 日本乱人伦a精品| 亚洲三级 欧美三级| 欧美日韩国产在线看| 中国china体内裑精亚洲片| 亚洲精品av在线| 亚洲成**性毛茸茸| 亚洲天堂免费观看| 最近2019年日本中文免费字幕| 日韩va亚洲va欧洲va国产| 色先锋资源久久综合5566| 最好看的2019的中文字幕视频| 久久久久免费精品国产| 在线电影中文日韩| 国产成人激情小视频| 久久视频免费在线播放| 欧美日韩午夜剧场| 91久久久亚洲精品| 国产精国产精品| 久久久久一本一区二区青青蜜月| 亚洲人成电影网| 国产亚洲精品久久久优势| 日韩精品在线私人| 在线播放国产精品| 日韩美女毛茸茸| 92看片淫黄大片欧美看国产片| 国产亚洲欧美日韩美女| 97超碰色婷婷| 欧美黑人巨大精品一区二区| 亚洲免费中文字幕| 欧美亚洲日本黄色| 欧美亚洲另类激情另类| 97超碰国产精品女人人人爽| 羞羞色国产精品| 日本高清久久天堂| 亚洲视频在线观看视频| 国产福利成人在线| 一区二区亚洲精品国产| 欧美俄罗斯乱妇| 国产精品成久久久久三级| 亚洲免费小视频| 81精品国产乱码久久久久久| 亚洲第一二三四五区| 欧美性猛交xxxx乱大交蜜桃| 亚洲全黄一级网站| 日韩免费观看av| 亚洲嫩模很污视频| 久久精品视频亚洲| 久久久久久久久91| 奇门遁甲1982国语版免费观看高清| 91精品国产精品| 色av吧综合网| 亚洲国产精品人久久电影| 国产精品九九久久久久久久| 亚洲国产精品系列| 久久精品一本久久99精品| 亚洲r级在线观看| 欧美性精品220| 亚洲美女av电影| 欧美放荡办公室videos4k| 欧美大片在线看免费观看| 日韩国产高清视频在线| 久久99热精品| 欧美极品少妇xxxxⅹ喷水| 亚洲男女自偷自拍图片另类| 亚洲日韩欧美视频一区| 日韩欧美在线中文字幕| 成人国产精品日本在线| 欧美成人性生活| 自拍偷拍亚洲精品| 国模精品一区二区三区色天香| 97在线视频精品| 欧美大片在线免费观看| 成人激情视频免费在线| 久久久久国色av免费观看性色| 青草青草久热精品视频在线网站| 日韩精品视频免费在线观看| 欧美日韩福利在线观看| 日韩av色综合| 97超碰国产精品女人人人爽| 亚洲加勒比久久88色综合| 欧美日韩在线视频一区| 亚洲美女在线看| 亚洲欧美制服另类日韩| 最近的2019中文字幕免费一页| 精品国内自产拍在线观看| 国产视频精品久久久| 色黄久久久久久| 国语自产精品视频在线看抢先版图片| 欧美极度另类性三渗透| 亚洲在线第一页| 一道本无吗dⅴd在线播放一区| 国内精品视频久久| www.亚洲一区| 中文字幕国产亚洲| 91国自产精品中文字幕亚洲| 成人xvideos免费视频| 91久久精品国产91性色| 久久九九精品99国产精品| 91精品视频专区| 狠狠躁夜夜躁人人爽天天天天97| 性亚洲最疯狂xxxx高清| 欧美大片va欧美在线播放| 92福利视频午夜1000合集在线观看| 久久久精品视频成人| 国产午夜精品美女视频明星a级| 久久久久日韩精品久久久男男| 国产精品丝袜视频| 国产精品福利无圣光在线一区| 国产精品电影久久久久电影网| 日韩av片电影专区| 亚洲另类图片色| 欧美在线视频一二三| 97视频在线观看免费高清完整版在线观看| 久久久久久国产精品美女| 日韩av在线播放资源| 精品国产91久久久| 亚洲伊人久久综合| 亚洲美女视频网| 中文字幕精品一区二区精品| 亚洲成人免费网站| 亚洲国产日韩欧美综合久久| 92国产精品久久久久首页| 色综合天天狠天天透天天伊人| 最近中文字幕mv在线一区二区三区四区| 日韩毛片在线观看| 日本一欧美一欧美一亚洲视频| www.美女亚洲精品| 成人免费在线视频网站| 亚洲一区二区少妇| 国产精品视频白浆免费视频| 亚洲影院高清在线| 久久九九亚洲综合| 亚洲激情免费观看| 日韩高清电影免费观看完整版| 欧美性猛交xxxx乱大交| 美女视频黄免费的亚洲男人天堂| 久久久久北条麻妃免费看| 富二代精品短视频| 久久久99久久精品女同性| 国产精品三级久久久久久电影| 久久在精品线影院精品国产| 九九久久国产精品| 在线日韩日本国产亚洲| 成人乱色短篇合集| 欧美做爰性生交视频| 久久精品99久久香蕉国产色戒| 国产精品美乳一区二区免费| 国产欧美韩国高清| 亚洲精品中文字幕女同| 久久久精品日本| 久久精品国产91精品亚洲|