android3d旋转动画
⑴ 求助,怎么用android实现控件的3D立体旋转效果
实现水平滑动,所以可在手势抬起的时候进行判断并处理,是滑动显得流畅,代码如下:
java">packagecom.example.rotation3dview;
importandroid.content.Context;
importandroid.graphics.Camera;
importandroid.graphics.Canvas;
importandroid.graphics.Matrix;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.VelocityTracker;
importandroid.view.View;
importandroid.view.ViewDebug.HierarchyTraceType;
importandroid.view.ViewGroup;
importandroid.widget.ImageView;
importandroid.widget.Scroller;
{
privateintmCurScreen=1;
//滑动的速度
privatestaticfinalintSNAP_VELOCITY=500;
;
privateintmWidth;
privateScrollermScroller;
privateCameramCamera;
privateMatrixmMatrix;
//旋转的角度,可以进行修改来观察效果
privatefloatangle=90;
publicRote3DView(Contextcontext,AttributeSetattrs){
super(context,attrs);
mScroller=newScroller(context);
mCamera=newCamera();
mMatrix=newMatrix();
initScreens();
}
publicvoidinitScreens(){
ViewGroup.LayoutParamsp=newViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
for(inti=0;i<3;i++){
this.addView(newImageView(this.getContext()),i,p);
}
((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);
((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);
((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);
}
@Override
protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
intchildLeft=0;
finalintchildCount=getChildCount();
for(inti=0;i<childCount;i++){
finalViewchildView=getChildAt(i);
if(childView.getVisibility()!=View.GONE){
finalintchildWidth=childView.getMeasuredWidth();
childView.layout(childLeft,0,childLeft+childWidth,childView.getMeasuredHeight());
childLeft+=childWidth;
}
}
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
finalintwidth=MeasureSpec.getSize(widthMeasureSpec);
finalintwidthMode=MeasureSpec.getMode(widthMeasureSpec);
if(widthMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintheightMode=MeasureSpec.getMode(heightMeasureSpec);
if(heightMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintcount=getChildCount();
for(inti=0;i<count;i++){
getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
}
scrollTo(mCurScreen*width,0);
}
privatefloatmDownX;
@Override
publicbooleanonTouchEvent(MotionEventevent){
if(mVelocityTracker==null){
mVelocityTracker=VelocityTracker.obtain();
}
//将当前的触摸事件传递给VelocityTracker对象
mVelocityTracker.addMovement(event);
floatx=event.getX();
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
mDownX=x;
break;
caseMotionEvent.ACTION_MOVE:
intdisX=(int)(mDownX-x);
mDownX=x;
scrollBy(disX,0);
break;
caseMotionEvent.ACTION_UP:
=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
intvelocityX=(int)velocityTracker.getXVelocity();
if(velocityX>SNAP_VELOCITY&&mCurScreen>0){
snapToScreen(mCurScreen-1);
}elseif(velocityX<-SNAP_VELOCITY&&mCurScreen<getChildCount()-1){
snapToScreen(mCurScreen+1);
}else{
snapToDestination();
}
if(mVelocityTracker!=null){
mVelocityTracker.recycle();
mVelocityTracker=null;
}
break;
}
returntrue;
}
@Override
publicvoidcomputeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
publicvoidsnapToDestination(){
setMWidth();
finalintdestScreen=(getScrollX()+mWidth/2)/mWidth;
snapToScreen(destScreen);
}
publicvoidsnapToScreen(intwhichScreen){
whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-1));
setMWidth();
intscrollX=getScrollX();
intstartWidth=whichScreen*mWidth;
if(scrollX!=startWidth){
intdelta=0;
intstartX=0;
if(whichScreen>mCurScreen){
setPre();
delta=startWidth-scrollX;
startX=mWidth-startWidth+scrollX;
}elseif(whichScreen<mCurScreen){
setNext();
delta=-scrollX;
startX=scrollX+mWidth;
}else{
startX=scrollX;
delta=startWidth-scrollX;
}
mScroller.startScroll(startX,0,delta,0,Math.abs(delta)*2);
invalidate();
}
}
privatevoidsetNext(){
intcount=this.getChildCount();
Viewview=getChildAt(count-1);
removeViewAt(count-1);
addView(view,0);
}
privatevoidsetPre(){
intcount=this.getChildCount();
Viewview=getChildAt(0);
removeViewAt(0);
addView(view,count-1);
}
privatevoidsetMWidth(){
if(mWidth==0){
mWidth=getWidth();
}
}
}
实现立体效果,添加如下代码:
/*
*当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制调用drawScreen函数
*/
@Override
protectedvoiddispatchDraw(Canvascanvas){
finallongdrawingTime=getDrawingTime();
finalintcount=getChildCount();
for(inti=0;i<count;i++){
drawScreen(canvas,i,drawingTime);
}
}
publicvoiddrawScreen(Canvascanvas,intscreen,longdrawingTime){
//得到当前子View的宽度
finalintwidth=getWidth();
finalintscrollWidth=screen*width;
finalintscrollX=this.getScrollX();
//偏移量不足的时
if(scrollWidth>scrollX+width||scrollWidth+width<scrollX){
return;
}
finalViewchild=getChildAt(screen);
finalintfaceIndex=screen;
finalfloatcurrentDegree=getScrollX()*(angle/getMeasuredWidth());
finalfloatfaceDegree=currentDegree-faceIndex*angle;
if(faceDegree>90||faceDegree<-90){
return;
}
finalfloatcenterX=(scrollWidth<scrollX)?scrollWidth+width
:scrollWidth;
finalfloatcenterY=getHeight()/2;
finalCameracamera=mCamera;
finalMatrixmatrix=mMatrix;
canvas.save();
camera.save();
camera.rotateY(-faceDegree);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX,-centerY);
matrix.postTranslate(centerX,centerY);
canvas.concat(matrix);
drawChild(canvas,child,drawingTime);
canvas.restore();
}
⑵ android怎样实现多张图片的旋转木马切换的3d特效
我们最近在整理一款这样的包含各种3d效果的SDK,到时发布了给你用
⑶ android里面3d动画怎么做啊,求大神指导
是单纯说动画怎么做还是说安卓里面有交互功能的动画怎么做?
单纯做3D动画,你懂得MAYA 3DMAX等软件的操作即可,熟悉建模、贴图、绑定、动画、灯光渲染等模块,懂得动画的运动规律。
如果是带交互的动画,这就涉及更广了,像游戏的话,首先你必须得会写代码,会使用类似Angle 2D engine 、Rokon、Catcake、jPCT、U3D等等一些游戏引擎。然后当然,你会做3D动画。
⑷ android仿饿了么加入购物车旋转控件动画按钮
这个二维控件不支持,你可以对按钮进行动画式的先变窄再变宽,并进行颜色变换,从而达到模拟立体翻转的效果。更推荐的方法是直接使用WPF的3D功能,制作长方形,并在正反面都使用VisualBrush,而VisualBrush绑定到控件,使得这个长方形看起来像一个立体的按钮,并且拥有正反面,最后使用Transform3D派生的Rotetransform3D进行真正意义上的旋转。
⑸ Android 旋转动画
<rotate
android:fromDegrees="45"//起始旋转的角度
android:toDegrees="89"//结束选装后的角度
android:ration="500"//执行时间为500ms
android:pivotX="50%"//距离控件左边缘50%
android:pivotY="50%"//距离控件上边缘50%(与上边结合就是控件中心)
android:fillEnabled="true"
android:fillAfter="true"//动画执行完后停留在执行完的状态
/>
—————————————————————————————————————————
当然也可以通过代码用animation实现
好久没写,应该是
RotateAnimationanimation=newRotateAnimation(0f,45f,Animation.RELATIVE_TO_SELF,
0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animation.setDuration(500);
view.setAnimation(animation);
⑹ Android 旋转动画怎么动态设置旋转角度,用
RotateAnimation rotateAnimation = new RotateAnimation(0, 180, centerX, centerY);
其中第一个参数表示动画的起始角度,第二个参数表示动画的结束角度。
⑺ android中的动画有哪几类
在Android3.0(即API Level11)以前,Android仅支持2种动画:分别是Frame Animation(逐帧动画)和Tween Animation(补间动画),在3.0之后Android支持了一种新的动画系统,称为:Property Animation(属性动画)。
一、Frame Animation:(逐帧动画)
这个很好理解,一帧帧的播放图片,利用人眼视觉残留原理,给我们带来动画的感觉。它的原理的GIF图片、电影播放原理一样。
1.定义逐帧动画比较简单,只要在中使用子元素定义所有播放帧即可。
(1) android:oneshot 设置是否仅播放一次
(2) android:drawable 设置每一帧图片
(3) android:ration 设置图片间切换间隔
2.习惯上把AnimationDrawable设置为ImageView的背景
android:background=@anim/frame_anim
然后我们就可以在java代码中获取AnimationDrawable对象了
AnimationDrawable anim = (AnimationDrawable)imageView.getBackground();
(需要注意的是,AnimationDrawable默认是不播放的,调用其start()方法开始播放,stop停止播放)
3.上面的动画文件是通过xml文件来配置的,如果你喜欢,也可以通过在java代码中创建AnimationDrawable对象,然后通过addFrame(Drawable frame, int ration)方法向动画添加帧,然后start()。。。
二、Tween Animation:(补间动画)
补间动画就是我们只需指定开始、结束的“关键帧“,而变化中的其他帧由系统来计算,不必自己一帧帧的去定义。
1. Android使用Animation代表抽象动画,包括四种子类:AlphaAnimation(透明度动画)、ScaleAnimation(缩放动画)、TranslateAnimation(位移动画)、RotateAnimation(透明度动画)。Android里面允许在java中创建Animation类对象,但是一般都会采用动画资源文件来定义动画,把界面与逻辑分离
<set android:interpolator="@android:anim/linear_interpolator" xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 定义透明度的变换 -->
<!-- 定义旋转变换 -->
<rotate android:ration="3000/" android:fromdegrees="0" android:pivotx="50%" android:pivoty="50%" android:todegrees="1800">
</rotate></alpha></set>
(一个set可以同时定义多个动画,一起执行。)
2. android:interpolator=@android:anim/linear_interpolator控制动画期间需要补入多少帧,简单来说就是控制动画速度,有些地方翻译为“插值“。Interpolator有几种实现类:LinearInterpolator、AccelerateInterpolator、、CycleInterpolator、DecelerateInterpolator,具体使用可以参考官方API Demo。
3. 定义好anim文件后,我们可以通过AnimationUtils工具类来加载它们,加载成功后返回一个Animation。然后就可以通过View的startAnimation(anim)开始执行动画了。
Animation anim = AnimationUtils.loadAnimation(this, R.anim.anim);
//设置动画结束后保留结束状态
anim.setFillAfter(true);
//设置插值效果
anim.setInterpolator(interpolator);
//对view执行动画
view. startAnimation(anim);
三、Property Animation:(属性动画)
属性动画,这个是在Android 3.0中才引进的,它可以直接更改我们对象的属性。在上面提到的Tween Animation中,只是更改View的绘画效果而View的真实属性是不改变的。假设你用Tween动画将一个Button从左边移到右边,无论你怎么点击移动后的Button,他都没有反应。而当你点击移动前Button的位置时才有反应,因为Button的位置属性木有改变。而Property Animation则可以直接改变View对象的属性值,这样可以让我们少做一些处理工作,提高效率与代码的可读性。
(1)ValueAnimator:包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。应用ValueAnimator有两个步骤
1计算属性值。
2根据属性值执行相应的动作,如改变对象的某一属性。
我们的主是第二步,需要实现ValueAnimator.onUpdateListener接口,这个接口只有一个函数onAnimationUpdate(),将要改变View对象属性的事情在该接口中do。
animation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//do your work
}
});
(2)ObjectAnimator:继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,应该满足以下条件:
1.对象应该有一个setter函数:set(驼峰命名法)
2如下面的例子,像ofFloat之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数只设置了一个值的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法:get
3如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。
ObjectAnimator oa=ObjectAnimator.ofFloat(tv, alpha, 0f, 1f);
oa.setDuration(3000);
oa.start();
如果不满足上面的条件,我们只能乖乖的使用ValueAnimator来创建动画。
(3)Animator.AnimatorListener:可以为Animator设置动画监听,需要重写下面四个方法。
onAnimationStart()
onAnimationEnd()
onAnimationRepeat()
onAnimationCancel()
这里我们也可以实现AnimatorListenerAdapter,他的好处是可以只用定义想监听的事件而不用实现每个函数却只定义一空函数体。如下:
anim.addListener(new AnimatorListenerAdapter() {
public void on AnimationEnd(Animator animation){
//do your work
}
});
(4)AnimationSet:可以组合多个动画共同工作
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(anim1).before(anim2);
bouncer.play(anim2).with(anim3);
bouncer.play(anim2).with(anim4)
bouncer.play(anim5).after(amin2);
animatorSet.start();
上面的代码意思是: 首先播放anim1;同时播放anim2,anim3,anim4;最后播放anim5。
(5)TimeInterplator:与Tween中的interpolator类似。有以下几种
AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator 反向 ,先向相反方向改变一段再加速播放
反向加回弹,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)
LinearInterpolator 线性,线性均匀改变
OvershottInterpolator 回弹,最后超出目的值然后缓慢改变到目的值
TimeInterpolator 一个接口,允许你自定义interpolator,以上几个都是实现了这个接口
(6)Keyframes:可以让我们定义除了开始和结束以外的关键帧。KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,如下:
Keyframe kf0 = Keyframe.ofInt(0, 400);
Keyframe kf1 = Keyframe.ofInt(0.25f, 200);
Keyframe kf2 = Keyframe.ofInt(0.5f, 400);
Keyframe kf4 = Keyframe.ofInt(0.75f, 100);
Keyframe kf3 = Keyframe.ofInt(1f, 500);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(width, kf0, kf1, kf2, kf4, kf3);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(btn, pvhRotation);
上述代码的意思是:设置btn对象的width属性值使其:开始时 Width=400,动画开始1/4时 Width=200,动画开始1/2时 Width=400,动画开始3/4时 Width=100,动画结束时 Width=500。
(7)ViewPropertyAnimator:对一个View同时改变多种属性,非常推荐用这种。该类对多属性动画进行了优化,会合并一些invalidate()来减少刷新视图。而且使用起来非常简便,但是要求API LEVEL 12,即Android 3.1以上。仅需要一行代码即可完成水平、竖直移动
myView.animate().translationX(50f). translationY(100f);
(8)常需要改变的一些属性:
translationX,translationY: View相对于原始位置的偏移量
rotation,rotationX,rotationY: 旋转,rotation用于2D旋转角度,3D中用到后两个
scaleX,scaleY: 缩放比
x,y: View的最终坐标,是View的left,top位置加上translationX,translationY
alpha: 透明度
四、最后自己总结一下这三种动画的优缺点:
(1)Frame Animation(帧动画)主要用于播放一帧帧准备好的图片,类似GIF图片,优点是使用简单方便、缺点是需要事先准备好每一帧图片;
(2)Tween Animation(补间动画)仅需定义开始与结束的关键帧,而变化的中间帧由系统补上,优点是不用准备每一帧,缺点是只改变了对象绘制,而没有改变View本身属性。因此如果改变了按钮的位置,还是需要点击原来按钮所在位置才有效。
(3)Property Animation(属性动画)是3.0后推出的动画,优点是使用简单、降低实现的复杂度、直接更改对象的属性、几乎可适用于任何对象而仅非View类,缺点是需要3.0以上的API支持,限制较大!但是目前国外有个开源库,可以提供低版本支持!
⑻ android中怎么定义旋转动画的旋转速度
android源代码之Rotate旋转动画
标签为旋转节点
Tween一共为我们提供了3种动画渲染模式。
android:interpolator="@android:anim/accelerate_interpolator" 设置动画渲染器为加速动画(动画播放中越来越快)
android:interpolator="@android:anim/decelerate_interpolator" 设置动画渲染器为减速动画(动画播放中越来越慢)
android:interpolator="@android:anim/accelerate_decelerate_interpolator" 设置动画渲染器为先加速在减速(开始速度最快 逐渐减慢)
如果不写的话 默认为匀速运动
android:fromDegrees="+360"设置动画开始的角度
android:toDegrees="0"设置动画结束的角度
这个动画布局设置动画将向左做360度旋转加速运动。
android:interpolator="@android:anim/accelerate_interpolator"
android:fromDegrees="+360"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:ration="2000"
/>
复制代码
代码实现
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
public class RotateActivity extends Activity {
/**向左旋转动画按钮**/
Button mButton0 = null;
/**向右旋转动画按钮**/
Button mButton1 = null;
/**显示动画的ImageView**/
ImageView mImageView = null;
/**向左旋转动画**/
Animation mLeftAnimation = null;
/**向右旋转动画**/
Animation mRightAnimation = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.retate);
/**拿到ImageView对象**/
mImageView = (ImageView)findViewById(R.id.imageView);
/**加载向左与向右旋转动画**/
mLeftAnimation = AnimationUtils.loadAnimation(this, R.anim.retateleft);
mRightAnimation = AnimationUtils.loadAnimation(this, R.anim.retateright);
mButton0 = (Button)findViewById(R.id.button0);
mButton0.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
/**播放向左旋转动画**/
mImageView.startAnimation(mLeftAnimation);
}
});
mButton1 = (Button)findViewById(R.id.button1);
mButton1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
/**播放向右旋转动画**/
mImageView.startAnimation(mRightAnimation);
}
});
}
}
⑼ 如何实现Rotate旋转动画的android源代码
android源代码之Rotate旋转动画
标签为旋转节点
Tween一共为我们提供了3种动画渲染模式。
android:interpolator="@android:anim/accelerate_interpolator" 设置动画渲染器为加速动画(动画播放中越来越快)
android:interpolator="@android:anim/decelerate_interpolator" 设置动画渲染器为减速动画(动画播放中越来越慢)
android:interpolator="@android:anim/accelerate_decelerate_interpolator" 设置动画渲染器为先加速在减速(开始速度最快 逐渐减慢)
如果不写的话 默认为匀速运动
android:fromDegrees="+360"设置动画开始的角度
android:toDegrees="0"设置动画结束的角度
这个动画布局设置动画将向左做360度旋转加速运动。
android:interpolator="@android:anim/accelerate_interpolator"
android:fromDegrees="+360"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:ration="2000"
/>
复制代码
代码实现
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
public class RotateActivity extends Activity {
/**向左旋转动画按钮**/
Button mButton0 = null;
/**向右旋转动画按钮**/
Button mButton1 = null;
/**显示动画的ImageView**/
ImageView mImageView = null;
/**向左旋转动画**/
Animation mLeftAnimation = null;
/**向右旋转动画**/
Animation mRightAnimation = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.retate);
/**拿到ImageView对象**/
mImageView = (ImageView)findViewById(R.id.imageView);
/**加载向左与向右旋转动画**/
mLeftAnimation = AnimationUtils.loadAnimation(this, R.anim.retateleft);
mRightAnimation = AnimationUtils.loadAnimation(this, R.anim.retateright);
mButton0 = (Button)findViewById(R.id.button0);
mButton0.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
/**播放向左旋转动画**/
mImageView.startAnimation(mLeftAnimation);
}
});
mButton1 = (Button)findViewById(R.id.button1);
mButton1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
/**播放向右旋转动画**/
mImageView.startAnimation(mRightAnimation);
}
});
}
}
学习更多关于android源代码,可以查询