Android 3D旋转 Layout
来源:互联网 发布:linux grub命令进win 编辑:程序博客网 时间:2024/05/29 05:00
一款3D Layout,他可以让任何view拥有3D效果,可以触摸展示3D效果,或者执行翻转动画。
废话不多说,先上图:
如何使用
- 将ThreeDLayout包裹你想要的布局(注意:ThreeDlayout只能有一个子view)
<com.wingsofts.threedlayout.ThreeDLayout android:background="@color/colorPrimary" android:id="@+id/td_header" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView" android:text="30℃" android:textColor="#fff" android:gravity="center" android:textSize="80sp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </com.wingsofts.threedlayout.ThreeDLayout>
之后,调用以下方法有对应效果
//开启触摸模式layout.setTouchable(true);//改变触摸模式layout.setTouchMode(ThreeDLayout.MODE_BOTH_X_Y);//开始执行动画startVerticalAnimate(long duration);startVerticalAnimateDelayed(final long delayed, final long duration)startHorizontalAnimate(long duration)startHorizontalAnimateDelayed(final long delayed, final long duration)//开启循环动画startHorizontalAnimate()//关闭循环动画stopAnimate()
ThreeLayout代码:粘贴到项目中即可使用:
public class ThreeDLayout extends ViewGroup { private Camera mCamera; private Matrix mMatrix; //this viewgroup's center private int mCenterX; private int mCenterY; //rotateDegree private float mCanvasRotateY; private float mCanvasRotateX; private float mCanvasMaxRotateDegree = 50; //the touch mode public static int MODE_X = 0; public static int MODE_Y = 1; public static int MODE_BOTH_X_Y = 2; private int mMode = MODE_BOTH_X_Y; private float mDensity; private float[] mValues = new float[9]; //the flag of touch private boolean isCanTouch = false; //the degree of animation private float mDegreeY = 0; private float mDegreeX = 0; //the flag of animate private boolean isPlaying = false; //the degree of longer animate private int mLoopAnimateY = 0; public ThreeDLayout(Context context) { this(context, null); } public ThreeDLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ThreeDLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //set a default background to make sure onDraw() dispatch if (getBackground() == null) { setBackgroundColor(Color.parseColor("#ffffff")); } DisplayMetrics dm = new DisplayMetrics(); dm = getResources().getDisplayMetrics(); mDensity = dm.density; mCamera = new Camera(); mMatrix = new Matrix(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (getChildCount() != 1) { throw new IllegalStateException("ThreeDLayout can only have one child"); } View child = getChildAt(0); measureChild(child, widthMeasureSpec, heightMeasureSpec); //only one child view,so give the same size setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight()); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { View child = getChildAt(0); child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight()); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mCenterX = w / 2; mCenterY = h / 2; } @Override protected void onDraw(Canvas canvas) { mMatrix.reset(); mCamera.save(); if (mMode == MODE_Y || mMode == MODE_BOTH_X_Y) { mCamera.rotateX(mCanvasRotateX); } if (mMode == MODE_X || mMode == MODE_BOTH_X_Y) { mCamera.rotateY(mCanvasRotateY); } mCamera.rotateY(mDegreeY); mCamera.rotateX(mDegreeX); if (isPlaying) { mCamera.rotateY(mLoopAnimateY++); Log.e("wing", mLoopAnimateY + ""); if (mLoopAnimateY == 360) { mLoopAnimateY = 0; } invalidate(); } mCamera.getMatrix(mMatrix); // fix the Camera bug, mMatrix.getValues(mValues); mValues[6] = mValues[6] / mDensity; mValues[7] = mValues[7] / mDensity; mMatrix.setValues(mValues); mCamera.restore(); mMatrix.preTranslate(-mCenterX, -mCenterY); mMatrix.postTranslate(mCenterX, mCenterY); canvas.concat(mMatrix); super.onDraw(canvas); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (isCanTouch) { return true; } else { return super.onInterceptTouchEvent(ev); } } @Override public boolean onTouchEvent(MotionEvent event) { if (isCanTouch) { float x = event.getX(); float y = event.getY(); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_MOVE: { rotateCanvasWhenMove(x, y); invalidate(); return true; } case MotionEvent.ACTION_UP: { mDegreeY = 0; rotateCanvasWhenMove(mCenterX, mCenterY); invalidate(); return true; } } return true; } else { return super.onTouchEvent(event); } } /** * get the value to rotate */ private void rotateCanvasWhenMove(float x, float y) { float dx = x - mCenterX; float dy = y - mCenterY; float percentX = dx / mCenterX; float percentY = dy / mCenterY; if (percentX > 1f) { percentX = 1f; } else if (percentX < -1f) { percentX = -1f; } if (percentY > 1f) { percentY = 1f; } else if (percentY < -1f) { percentY = -1f; } mCanvasRotateY = mCanvasMaxRotateDegree * percentX; mCanvasRotateX = -(mCanvasMaxRotateDegree * percentY); } public void setTouchable(boolean canTouch) { isCanTouch = canTouch; } public void setTouchMode(int mode) { mMode = mode; isCanTouch = true; } /** * set the max rotate degree */ public void setMaxRotateDegree(int degree) { mCanvasMaxRotateDegree = degree; } /** * start horizontal turn animate */ public void startHorizontalAnimate(long duration) { final ValueAnimator animator = ValueAnimator.ofFloat(-180f, 0f); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mDegreeY = (float) animation.getAnimatedValue(); invalidate(); } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { mDegreeY = 0; animator.removeAllUpdateListeners(); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animator.setDuration(duration); animator.start(); } /** * start horizontal turn animate delayed */ public void startHorizontalAnimateDelayed(final long delayed, final long duration) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(delayed); } catch (InterruptedException e) { e.printStackTrace(); } post(new Runnable() { @Override public void run() { startHorizontalAnimate(duration); } }); } }).start(); } /** * start vertical turn animate */ public void startVerticalAnimate(long duration) { final ValueAnimator animator = ValueAnimator.ofFloat(-180f, 0f); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mDegreeX = (float) animation.getAnimatedValue(); invalidate(); } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { mDegreeX = 0; animator.removeAllUpdateListeners(); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animator.setDuration(duration); animator.start(); } /** * start vertical turn animate delayed */ public void startVerticalAnimateDelayed(final long delayed, final long duration) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(delayed); } catch (InterruptedException e) { e.printStackTrace(); } post(new Runnable() { @Override public void run() { startVerticalAnimate(duration); } }); } }).start(); } /** * start loop animate */ public void startHorizontalAnimate() { isPlaying = true; invalidate(); } /** * stop the loop animate */ public void stopAnimate() { isPlaying = false; mLoopAnimateY = 0; invalidate(); }}
Demo下载地址
0 0
- Android 3D旋转 Layout
- 3d旋转 android
- Android的3D旋转
- Android的3D旋转
- Android的3D旋转
- android布局3D旋转
- Android 3D旋转动画
- android layout 3D切换效果
- Android实现3D旋转效果
- android 控件 3d 旋转效果
- Android 3D旋转动画效果
- Android应用: 3D旋转球
- Android 3D旋转动画效果
- Android 3D旋转动画实现
- android 实现3D动画旋转效果
- Android 3D旋转动画效果
- Android 3D 旋转 木马 Carousel
- Android 3D旋转动画效果
- Linux系统中切换用户身份su与sudo的用法与实例
- 基于labwindows 应用PDFlib自动生成PDF文件
- 一起学opencv (五) 图片的数据计较,类的应用
- JQuery监听页面滚动总结
- android开发,绘制圆形图片并添加文字居中显示
- Android 3D旋转 Layout
- 如何使用virtualenvwrapper切换不同版本的python
- Android,PullToRefreshListView,addHeaderView错误!
- Handler内存泄漏分析及解决
- XML布局文件出错问题解决办法
- JavaScript trim 实现(去除字符串首尾指定字符)
- C++中,类成员的private和public有什么区别?
- android逆向分析之从smali到java
- 百度地图相关——结合下拉刷新功能重新定位