`

绕Y轴翻转

阅读更多

Android中并没有提供直接做3D翻转的动画,所以关于3D翻转的动画效果需要我们自己实现,那么我们首先来分析一下Animation 和 Transformation。

Animation动画的主要接口,其中主要定义了动画的一些属性比如开始时间,持续时间,是否重复播放等等。而 Transformation中则包含一个矩阵和alpha值,矩阵是用来做平移,旋转和缩放动画的,而alpha值是用来做alpha动画的,要实现 3D旋转动画我们需要继承自Animation类来实现,我们需要重载getTransformation和applyTransformation,在 getTransformation中Animation会根据动画的属性来产生一系列的差值点,然后将这些差值点传给 applyTransformation,这个函数将根据这些点来生成不同的Transformation。下面是具体实现:

  1. public   class  Rotate3dAnimation  extends  Animation {  
  2.      //开始角度  
  3.      private   final   float  mFromDegrees;  
  4.      //结束角度  
  5.      private   final   float  mToDegrees;  
  6.      //中心点  
  7.      private   final   float  mCenterX;  
  8.      private   final   float  mCenterY;  
  9.      private   final   float  mDepthZ;  
  10.      //是否需要扭曲  
  11.      private   final   boolean  mReverse;  
  12.      //摄像头  
  13.      private  Camera mCamera;  
  14.      public  Rotate3dAnimation( float  fromDegrees,  float  toDegrees,  
  15.              float  centerX,  float  centerY,  float  depthZ,  boolean  reverse) {  
  16.         mFromDegrees = fromDegrees;  
  17.         mToDegrees = toDegrees;  
  18.         mCenterX = centerX;  
  19.         mCenterY = centerY;  
  20.         mDepthZ = depthZ;  
  21.         mReverse = reverse;  
  22.     }  
  23.  
  24.      @Override  
  25.      public   void  initialize( int  width,  int  height,  int  parentWidth,  int  parentHeight) {  
  26.          super .initialize(width, height, parentWidth, parentHeight);  
  27.         mCamera =  new  Camera();  
  28.     }  
  29.      //生成Transformation  
  30.      @Override  
  31.      protected   void  applyTransformation( float  interpolatedTime, Transformation t) {  
  32.          final   float  fromDegrees = mFromDegrees;  
  33.          //生成中间角度  
  34.          float  degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);  
  35.  
  36.          final   float  centerX = mCenterX;  
  37.          final   float  centerY = mCenterY;  
  38.          final  Camera camera = mCamera;  
  39.  
  40.          final  Matrix matrix = t.getMatrix();  
  41.  
  42.         camera.save();  
  43.          if  (mReverse) {  
  44.             camera.translate( 0 .0f,  0 .0f, mDepthZ * interpolatedTime);  
  45.         }  else  {  
  46.             camera.translate( 0 .0f,  0 .0f, mDepthZ * ( 1 .0f - interpolatedTime));  
  47.         }  
  48.         camera.rotateY(degrees);  
  49.          //取得变换后的矩阵  
  50.         camera.getMatrix(matrix);  
  51.         camera.restore();  
  52.  
  53.         matrix.preTranslate(-centerX, -centerY);  
  54.         matrix.postTranslate(centerX, centerY);  
  55.     }  

其中包括了旋转的开始和结束角度,中心点、是否扭曲、和一个Camera,这里我们主要分析applyTransformation函 数,其中第一个参数就是通过getTransformation函数传递的差指点,然后我们根据这个差值通过线性差值算法计算出一个中间角度 degrees,Camera类是用来实现绕Y轴旋转后透视投影的,因此我们首先通过t.getMatrix()取得当前的矩阵,然后通过 camera.translate来对矩阵进行平移变换操作,camera.rotateY进行旋转。这样我们就可以很轻松的实现3D旋转效果了,该例子 的原意是通过一个列表来供用户选择要实现翻转的图像,所以我们分析至少需要定义两个控件:ListView和ImageView(要翻转的图像),主界面 的xml布局定义如下所示。

  1. < FrameLayout   xmlns:android = "http://schemas.android.com/apk/res/android"  
  2.      android:id = "@+id/container"  
  3.      android:layout_width = "match_parent"  
  4.      android:layout_height = "match_parent" >  
  5.  
  6.      < ListView  
  7.          android:id = "@android:id/list"  
  8.          android:persistentDrawingCache = "animation|scrolling"  
  9.          android:layout_width = "match_parent"  
  10.          android:layout_height = "match_parent"  
  11.          android:layoutAnimation = "@anim/layout_bottom_to_top_slide"   />  
  12.  
  13.      < ImageView  
  14.          android:id = "@+id/picture"  
  15.          android:scaleType = "fitCenter"  
  16.          android:layout_width = "match_parent"  
  17.          android:layout_height = "match_parent"  
  18.          android:visibility = "gone"   />  
  19.  
  20. </ FrameLayout >  

然后准备好需要的资源,在onCreate函数中准备好ListView和ImageView,因为要旋转所以我们需要保存视图的缓存 信息,通过setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);可以设 置该功能,当我们选择列表中的图像资源后在onItemClick中将选择的资源Id对应的图像设置到ImageView中,然后通过 applyRotation来启动一个动画,前面有了Rotate3dAnimation的实现,我们要完成3D翻转动画就很简单,直接构建一个 Rotate3dAnimation对象,设置其属性(包括动画监听),这里将动画的监听设置为DisplayNextView,可以用来显示下一个视 图,在其中的动画结束监听(onAnimationEnd)中,通过一个县城SwapViews来交换两个画面,交换过程则是设置ImageView和 ListView的显示相关属性,并构建一个Rotate3dAnimation对象,对另一个界面进行旋转即可,然后启动动画,整个转换过程实际上就是 将第一个界面从0度转好90度,然后就爱你过第二个界面从90度转到0度,这样就形成了一个翻转动画,完整代码如下,我们也加入了一些必要的注解,大家也 可以参考APIDemo中的Transition3d例子。

  1. public   class  Transition3d  extends  Activity  implements  
  2.         AdapterView.OnItemClickListener, View.OnClickListener {  
  3.      //照片列表  
  4.      private  ListView mPhotosList;  
  5.      private  ViewGroup mContainer;  
  6.      private  ImageView mImageView;  
  7.  
  8.      // 照片的名字,用于显示在list中  
  9.      private   static   final  String[] PHOTOS_NAMES =  new  String[] {  
  10.              "Lyon" ,  
  11.              "Livermore" ,  
  12.              "Tahoe Pier" ,  
  13.              "Lake Tahoe" ,  
  14.              "Grand Canyon" ,  
  15.              "Bodie"  
  16.     };  
  17.  
  18.      // 资源id  
  19.      private   static   final   int [] PHOTOS_RESOURCES =  new   int [] {  
  20.             R.drawable.photo1,  
  21.             R.drawable.photo2,  
  22.             R.drawable.photo3,  
  23.             R.drawable.photo4,  
  24.             R.drawable.photo5,  
  25.             R.drawable.photo6  
  26.     };  
  27.  
  28.      @Override  
  29.      protected   void  onCreate(Bundle savedInstanceState) {  
  30.          super .onCreate(savedInstanceState);  
  31.  
  32.         setContentView(R.layout.animations_main_screen);  
  33.  
  34.         mPhotosList = (ListView) findViewById(android.R.id.list);  
  35.         mImageView = (ImageView) findViewById(R.id.picture);  
  36.         mContainer = (ViewGroup) findViewById(R.id.container);  
  37.  
  38.          // 准备ListView  
  39.          final  ArrayAdapter adapter =  new  ArrayAdapter( this ,  
  40.                 android.R.layout.simple_list_item_1, PHOTOS_NAMES);  
  41.  
  42.         mPhotosList.setAdapter(adapter);  
  43.         mPhotosList.setOnItemClickListener( this );  
  44.  
  45.          // 准备ImageView  
  46.         mImageView.setClickable( true );  
  47.         mImageView.setFocusable( true );  
  48.         mImageView.setOnClickListener( this );  
  49.  
  50.          //设置需要保存缓存  
  51.         mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);  
  52.     }  
  53.  
  54.      /**  
  55.      * Setup a new 3D rotation on the container view.  
  56.      *  
  57.      * @param position the item that was clicked to show a picture, or -1 to show the list  
  58.      * @param start the start angle at which the rotation must begin  
  59.      * @param end the end angle of the rotation  
  60.      */  
  61.      private   void  applyRotation( int  position,  float  start,  float  end) {  
  62.          // 计算中心点  
  63.          final   float  centerX = mContainer.getWidth() /  2 .0f;  
  64.          final   float  centerY = mContainer.getHeight() /  2 .0f;  
  65.  
  66.          // Create a new 3D rotation with the supplied parameter  
  67.          // The animation listener is used to trigger the next animation  
  68.          final  Rotate3dAnimation rotation =  
  69.                  new  Rotate3dAnimation(start, end, centerX, centerY,  310 .0f,  true );  
  70.         rotation.setDuration( 500 );  
  71.         rotation.setFillAfter( true );  
  72.         rotation.setInterpolator( new  AccelerateInterpolator());  
  73.          //设置监听  
  74.         rotation.setAnimationListener( new  DisplayNextView(position));  
  75.  
  76.         mContainer.startAnimation(rotation);  
  77.     }  
  78.  
  79.      public   void  onItemClick(AdapterView parent, View v,  int  position,  long  id) {  
  80.          // 设置ImageView  
  81.         mImageView.setImageResource(PHOTOS_RESOURCES[position]);  
  82.         applyRotation(position,  0 90 );  
  83.     }  
  84.      //点击图像时,返回listview  
  85.      public   void  onClick(View v) {  
  86.         applyRotation(- 1 180 90 );  
  87.     }  
  88.  
  89.      /**  
  90.      * This class listens for the end of the first half of the animation.  
  91.      * It then posts a new action that effectively swaps the views when the container  
  92.      * is rotated 90 degrees and thus invisible.  
  93.      */  
  94.      private   final   class  DisplayNextView  implements  Animation.AnimationListener {  
  95.          private   final   int  mPosition;  
  96.  
  97.          private  DisplayNextView( int  position) {  
  98.             mPosition = position;  
  99.         }  
  100.  
  101.          public   void  onAnimationStart(Animation animation) {  
  102.         }  
  103.          //动画结束  
  104.          public   void  onAnimationEnd(Animation animation) {  
  105.             mContainer.post( new  SwapViews(mPosition));  
  106.         }  
  107.  
  108.          public   void  onAnimationRepeat(Animation animation) {  
  109.         }  
  110.     }  
  111.  
  112.      /**  
  113.      * This class is responsible for swapping the views and start the second  
  114.      * half of the animation.  
  115.      */  
  116.      private   final   class  SwapViews  implements  Runnable {  
  117.          private   final   int  mPosition;  
  118.  
  119.          public  SwapViews( int  position) {  
  120.             mPosition = position;  
  121.         }  
  122.  
  123.          public   void  run() {  
  124.              final   float  centerX = mContainer.getWidth() /  2 .0f;  
  125.              final   float  centerY = mContainer.getHeight() /  2 .0f;  
  126.             Rotate3dAnimation rotation;  
  127.               
  128.              if  (mPosition > - 1 ) {  
  129.                  //显示ImageView  
  130.                 mPhotosList.setVisibility(View.GONE);  
  131.                 mImageView.setVisibility(View.VISIBLE);  
  132.                 mImageView.requestFocus();  
  133.  
  134.                 rotation =  new  Rotate3dAnimation( 90 180 , centerX, centerY,  310 .0f,  false );  
  135.             }  else  {  
  136.                  //返回listview  
  137.                 mImageView.setVisibility(View.GONE);  
  138.                 mPhotosList.setVisibility(View.VISIBLE);  
  139.                 mPhotosList.requestFocus();  
  140.  
  141.                 rotation =  new  Rotate3dAnimation( 90 0 , centerX, centerY,  310 .0f,  false );  
  142.             }  
  143.  
  144.             rotation.setDuration( 500 );  
  145.             rotation.setFillAfter( true );  
  146.             rotation.setInterpolator( new  DecelerateInterpolator());  
  147.              //开始动画  
  148.             mContainer.startAnimation(rotation);  
  149.         }  
  150.     }  
  151.  
  152. }
分享到:
评论

相关推荐

    jQuery翻牌倒计时效果demo

    例如,我们可以使用`transform: rotateY(180deg)`来让元素绕Y轴翻转180度,从而达到翻面的效果。 JavaScript部分,我们可以设置一个定时器,每隔一定时间(如1秒)检查一次剩余时间,并更新界面。以下是一个简单的...

    jQuery css3鼠标悬停图片翻滚特效

    这段CSS代码中,`.roll`类是当鼠标悬停时添加的,`rotateY(180deg)`使得元素绕Y轴翻转180度,产生翻滚效果。`transition`属性定义了这个变换过程应该持续多久(0.5s)以及使用何种缓动函数(ease)来平滑地执行动画...

    HTML+CSS+JavaScript实现立体式图片旋转特效源码.zip

    /* 使图片绕Y轴翻转180度 */ } ``` 3. **JavaScript(JS)**:JavaScript是实现动态交互的关键,它允许根据用户的操作或时间间隔动态地改变HTML和CSS。在这个例子中,JavaScript可能会用来添加或移除上述CSS类(如...

    CSS图片3D旋转效果

    当鼠标悬停在元素上时,元素会沿着特定轴线进行旋转,这里提到的是沿着Y轴旋转,也就是垂直于屏幕的轴线,使得用户有一种图片翻转的感觉,增加了交互性和视觉吸引力。 要创建这样的3D旋转效果,我们需要了解以下几...

    CSS3悬停卡片重叠翻转特效

    当鼠标悬停在卡片上时,此属性将使卡片绕Y轴翻转180度,从而达到翻转效果。同时,我们还需要通过CSS3的伪类选择器`:hover`来控制鼠标悬停时的样式变化。 重叠效果则可以通过设置卡片的相对位置实现。我们可以通过...

    照相机示例

    2. **Y轴翻转**:绕Y轴的翻转会影响图像的上下位置。同样,180度旋转会使图像上下颠倒。在处理时,我们需要更新图像的坐标映射,使其在Y轴上的位置反转。 3. **Z轴翻转**:Z轴翻转涉及的是深度感知,通常与透视有关...

    HW1.zip_图片翻转_左右翻转

    // 参数1表示沿Y轴翻转 // 上下翻转 // cv::flip(image, image, 0); // 参数1表示沿X轴翻转 // 保存翻转后的图像 cv::imwrite("output.jpg", image); ``` 总的来说,“图片翻转”是图像处理中的基础操作,无论是...

    activity切换翻转效果

    通过改变矩阵的`m00`、`m11`和`m22`元素,可以实现绕X轴或Y轴的翻转。同时,需要考虑从哪个方向翻转,以及是否需要配合透视效果。 5. 目标Activity的动画:如果希望目标Activity也有类似效果,可以创建另一个自定义...

    仿iphone实现两个view切换翻转动画

    在进行翻转动画时,我们会对一个视图应用一个180度的绕Y轴旋转,从而模拟翻转效果。 接下来,我们来看看如何使用Swift语言实现这个动画效果。以下是一个简单的示例: ```swift import UIKit class ViewController...

    iOS图片翻转

    为了实现翻转效果,我们通常会先让视图绕Y轴旋转180度,然后恢复原状,从而给人一种翻转的感觉。代码示例如下: ```swift let flipTransform = CGAffineTransform(rotationAngle: .pi) view.transform = ...

    懒人原生纯CSS3静态图片翻转效果

    例如,如果要让一个图片元素`&lt;img id="flipImage" src="image.jpg"&gt;`沿着Y轴翻转,可以这样写: ```css #flipImage { transform: rotateY(180deg); } ``` 这个描述中提到的“附件中CSS属性”可能包含了一个示例...

    Duanxx的OpenCV学习:flip翻转图像

    - `-1`:表示同时沿两个轴翻转,即图像绕着图像中心翻转180度。 2. **翻转操作** `flip`函数的工作原理是通过交换图像对应像素的位置来实现翻转效果。例如,对于水平翻转,它会将原图像的左边缘像素与右边缘对应...

    纯CSS3实现3D骰子多角度翻转特效.zip

    同样,`rotateY(90deg)`会沿着Y轴翻转。通过组合这些旋转,我们可以模拟骰子的任意翻转动画。 为了使翻转动画平滑,我们可以使用CSS的`transition`属性。指定`transition: transform 0.5s;`将使得变换过程在0.5秒内...

    图片处理部分函数

    这个模式参数用于指定图片的处理方式,如直接绘制(0)、绕Y轴镜像翻转(0x2000)或绕X轴镜像翻转(0x4000)。函数通过设置Graphics对象的剪切区域来实现翻转效果,逐行或逐列地绘制图片。 在MIDP1.0中,由于不支持...

    jquery鼠标悬停图片翻转效果.zip

    - `transform: rotateY(180deg)`:这是实现水平翻转的关键,它通过绕Y轴旋转180度,使得元素看起来像是翻转了过来。 - `transform-origin`:这个属性可以设置变换的原点,决定元素从哪个位置开始翻转。 4. **...

    CSS3皇上翻牌子3D图片翻转动画代码

    例如,`rotateX(180deg)`会使元素绕X轴翻转180度,呈现出正面翻转到背面的效果。 2. **过渡效果**:为了使翻转过程平滑自然,我们需要使用`transition`属性来定义翻转动画的时长和速度曲线。例如,`transition: ...

    Qml翻转效果QmlFlipImage.7z

    - `scale`属性:设置元素的缩放比例,可以分别设置X和Y轴的缩放值。 - `pivotPoint`属性:与`origin`类似,定义缩放的中心点。 3. **动画(Animation)** - `Transition`和`State`:用于创建平滑的动画过渡,可以...

    css3实现3D色子翻转特效

    为了实现翻转效果,使用`transform`属性中的`rotateY`或者`rotateX`函数,这允许我们绕着Y轴或X轴旋转元素。例如,可以设置`.page`类在不同时间点的`rotateY`值,当它们在时间线上顺序被激活时,就会产生色子翻转的...

    纯css3实现的3D方块翻转动画特效源码.zip

    `:这三个函数分别用于绕X轴、Y轴和Z轴进行旋转。通过调整角度值,可以控制方块翻转的方向和程度。 3. `perspective: value;`:此属性定义了观察者与3D元素之间的距离,影响元素的透视效果,使3D变换看起来更加真实...

    三维旋转.zip

    2. **绕Y轴旋转**:绕Y轴旋转时,X和Z坐标发生变化,但Y坐标保持不变。这使得物体向左或向右倾斜。 3. **绕Z轴旋转**:类似地,绕Z轴旋转会影响X和Y坐标,而不改变Z坐标。这会让物体向前或向后翻转。 在计算机编程...

Global site tag (gtag.js) - Google Analytics