android
来源:互联网 发布:电信4g网络信号不好 编辑:程序博客网 时间:2024/06/06 07:37
参考:
camera、Matrix概念
Matrix的set,pre,post调用顺序
常用的API如下:
rotateX(float degree) 绕着x轴旋转degree个度数
rotateY(float degree) 绕着y轴旋转degree个度数
rotateZ(float degree) 绕着z轴旋转degree个度数
translate(float x,float y,float z) 平移一段距离
save()和restore() 作用跟Canvas的一样,保存原状态,操作完之后,恢复到原状态。
效果图:
好吧,电脑没显卡的弊端。。。
Rotate3dAnimation:3D动画
package com.example.rotatepicbrowserdemo;import android.view.animation.Animation;import android.view.animation.Transformation;import android.graphics.Camera;import android.graphics.Matrix;/** * 在两个指定角度之间绕Y轴旋转视图的动画。(3D动画) * <p> * 这个动画也在z轴(深度)上添加了一个转化来提高效果。 */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; /** * 在Y轴上创建一个新的3D旋转。旋转是由它的开始角和它的结束角来定义的。 * <p> * 旋转围绕在二维空间的一个中心点,确定由一对X和Y坐标,称为centerX 和 centerY. * <p> * 当动画开始时,执行z轴(深度)上的转化。可以指定转化的长度,以及转化是否应该及时倒转。 * * @param fromDegrees the start angle of the 3D rotation:3D旋转 起始角度 * @param toDegrees the end angle of the 3D rotation:3D旋转 结束角度 * @param centerX the X center of the 3D rotation:3D旋转 x轴中心 * @param centerY the Y center of the 3D rotation:3D旋转 Y轴中心 * @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(); //让Camera根据动画播放的时间在Z轴进行一定的偏移,使视图有远离视角的感觉。 if (mReverse) { // z的偏移会越来越大。这就会形成这样一个效果,view从近到远 camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { // z的偏移会越来越小。这就会形成这样一个效果, //我们的View从一个很远的地方向我们移过来,越来越近,最终移到了我们的窗口上面 camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } //让视图围绕Y轴进行旋转,从而产生立体旋转的效果 camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); //通过Matrix来确定旋转的中心点的位置。 matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }}
applyTransformation方法在旋转动画过程中不断调用,
interpolatedTime取值范围【0,1】,从0到1取值
Rotate3dFrameLayout:3D布局
public class Rotate3dFrameLayout extends FrameLayout { private View childView1; private View childView2; private float mCenterX; private float mCenterY; private int Duration = 150; private boolean mIsFirst; public Rotate3dFrameLayout(@NonNull Context context) { this(context, null); } public Rotate3dFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public Rotate3dFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //子View的数量 int childCount = getChildCount(); Log.e("111", "childCount=========" + childCount); if (childCount != 2) { throw new IllegalArgumentException("Rotate3dFrameLayout的子View数量必须为2"); } childView1 = getChildAt(0); childView2 = getChildAt(1); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mCenterX = w / 2; mCenterY = h / 2; Log.e("111", "mCenterX=========" + mCenterX); Log.e("111", "mCenterY=========" + mCenterY); } public void applyRotation(boolean isFirst) { Rotate3dAnimation rotation = null; mIsFirst = isFirst; float mDepthZ = 300.0f; if (mIsFirst) { rotation = new Rotate3dAnimation(0, 90, mCenterX, mCenterY, mDepthZ, true); } else { rotation = new Rotate3dAnimation(0, -90, mCenterX, mCenterY, mDepthZ, true); } rotation.setDuration(Duration); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateDecelerateInterpolator()); rotation.setAnimationListener(new DisplayNextView()); startAnimation(rotation); } private final class DisplayNextView implements Animation.AnimationListener { public void onAnimationStart(Animation animation) { } public void onAnimationEnd(Animation animation) { post(new SwapViews()); } public void onAnimationRepeat(Animation animation) { } } private final class SwapViews implements Runnable { @Override public void run() { Rotate3dAnimation rotation = null; if (mIsFirst) { childView1.setVisibility(View.GONE); childView2.setVisibility(View.VISIBLE); rotation = new Rotate3dAnimation(-90, 0, mCenterX, mCenterY, 310.0f, false); } else { childView1.setVisibility(View.VISIBLE); childView2.setVisibility(View.GONE); rotation = new Rotate3dAnimation(90, 0, mCenterX, mCenterY, 310.0f, false); } rotation.setDuration(Duration);//设置动画持续时间 rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateDecelerateInterpolator());//设置动画变化速度 startAnimation(rotation); } }}
父布局指定只能正反两个子布局。
布局:
<?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"> <com.yxl.test.Rotate3dFrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ff00"> <TextView android:id="@+id/childView1" android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center" android:layout_margin="20dp" android:background="@drawable/bg1" android:gravity="center" android:text="红" android:textColor="#000000" android:textSize="45sp" /> <TextView android:id="@+id/childView2" android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center" android:layout_margin="20dp" android:background="@drawable/bg2" android:gravity="center" android:text="蓝" android:textColor="#000000" android:textSize="45sp" android:visibility="gone" /> </com.yxl.test.Rotate3dFrameLayout></LinearLayout>
在Rotate3dFrameLayout中放置两个子布局:正反两面的两个布局。
MainActivityI
public class MainActivityI extends Activity { private Rotate3dFrameLayout container; private boolean isFirst = true;//默认第一面 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.rotate_layout); container = ((Rotate3dFrameLayout) this.findViewById(R.id.container)); container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { container.applyRotation(isFirst); isFirst = !isFirst; } }); }}
参考:Android立体旋转动画实现与封装(支持以X、Y、Z三个轴为轴心旋转)
阅读全文
0 0
- Android
- android
- Android
- android
- android
- Android
- Android
- android
- android
- android
- Android
- Android
- android!!!
- android
- android
- android
- android
- android:
- 数据结构与算法_字符串匹配
- <c:forEach>详解
- 链表插入排序-LintCode
- 解读 Maven 安装目录
- Ubuntu 14.04无U盘光盘在线安装完之后,重启之后出现“为/检查磁盘时发现严重错误。“的解决方法
- android
- AR 【WWDC2017 ARKit 技术理论】
- The given project is not a virtual component project
- C++ 实际运用Templates(5)---《C++ Templates》
- Spring 数据绑定 @RequestParam @ModelAttribute
- 如何成为一个优秀的高级C++程序员
- 单链表的所有操作,检查是否有环,合并链表,逆置链表,排序链表......
- cocos2dx 3.x TableView多行多列的使用
- 用kolla部署openstack遇到的问题总结