安卓3D旋转容器_实现任意视图3D旋转
发布日期:2021-06-29 18:29:51
浏览次数:2
分类:技术文章
本文共 7618 字,大约阅读时间需要 25 分钟。
关注 ,免费获取全套安卓开发学习资料
用途
支持对任何视图进行包裹后3D翻转.
效果图
主要代码
class ThreeDLayout(context: Context?, attrs: AttributeSet? = null) : ViewGroup(context, attrs) { private val mCamera: Camera private val mMatrix: Matrix //this viewgroup's center private var mCenterX = 0 private var mCenterY = 0 //rotateDegree private var mCanvasRotateY = 0f private var mCanvasRotateX = 0f private var mCanvasMaxRotateDegree = 50f private var mMode = MODE_BOTH_X_Y private val mDensity: Float private val mValues = FloatArray(9) //the flag of touch private var isCanTouch = false //the degree of animation private var mDegreeY = 0f private var mDegreeX = 0f //the flag of animate private var isPlaying = false //the degree of longer animate private var mLoopAnimateY = 0 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { check(childCount == 1) { "ThreeDLayout can only have one child" } val child = getChildAt(0) measureChild(child, widthMeasureSpec, heightMeasureSpec) //only one child view,so give the same size setMeasuredDimension(child.measuredWidth, child.measuredHeight) } override fun onLayout( changed: Boolean, l: Int, t: Int, r: Int, b: Int ) { val child = getChildAt(0) child.layout(0, 0, child.measuredWidth, child.measuredHeight) } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) mCenterX = w / 2 mCenterY = h / 2 } override fun 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++.toFloat()) 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.toFloat(), -mCenterY.toFloat()) mMatrix.postTranslate(mCenterX.toFloat(), mCenterY.toFloat()) canvas.concat(mMatrix) super.onDraw(canvas) } override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { return if (isCanTouch) { true } else { super.onInterceptTouchEvent(ev) } } override fun onTouchEvent(event: MotionEvent): Boolean { return if (isCanTouch) { val x = event.x val y = event.y when (event.action) { MotionEvent.ACTION_MOVE -> { rotateCanvasWhenMove(x, y) invalidate() return true } MotionEvent.ACTION_UP -> { mDegreeY = 0f rotateCanvasWhenMove(mCenterX.toFloat(), mCenterY.toFloat()) invalidate() return true } } true } else { super.onTouchEvent(event) } } /** * get the value to rotate */ private fun rotateCanvasWhenMove(x: Float, y: Float) { val dx = x - mCenterX val dy = y - mCenterY var percentX = dx / mCenterX var 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) } fun setTouchable(canTouch: Boolean) { isCanTouch = canTouch } fun setTouchMode(mode: Int) { mMode = mode isCanTouch = true } /** * set the max rotate degree */ fun setMaxRotateDegree(degree: Int) { mCanvasMaxRotateDegree = degree.toFloat() } /** * start horizontal turn animate */ fun startHorizontalAnimate(duration: Long) { val animator = ValueAnimator.ofFloat(-180f, 0f) animator.addUpdateListener { animation -> mDegreeY = animation.animatedValue as Float invalidate() } animator.addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator) { } override fun onAnimationEnd(animation: Animator) { mDegreeY = 0f animator.removeAllUpdateListeners() } override fun onAnimationCancel(animation: Animator) { } override fun onAnimationRepeat(animation: Animator) { } }) animator.duration = duration animator.start() } /** * start horizontal turn animate delayed */ fun startHorizontalAnimateDelayed(delayed: Long, duration: Long) { Thread(Runnable { try { Thread.sleep(delayed) } catch (e: InterruptedException) { e.printStackTrace() } post { startHorizontalAnimate(duration) } }).start() } /** * start vertical turn animate */ fun startVerticalAnimate(duration: Long) { val animator = ValueAnimator.ofFloat(-180f, 0f) animator.addUpdateListener { animation -> mDegreeX = animation.animatedValue as Float invalidate() } animator.addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator) { } override fun onAnimationEnd(animation: Animator) { mDegreeX = 0f animator.removeAllUpdateListeners() } override fun onAnimationCancel(animation: Animator) { } override fun onAnimationRepeat(animation: Animator) { } }) animator.duration = duration animator.start() } /** * start vertical turn animate delayed */ fun startVerticalAnimateDelayed(delayed: Long, duration: Long) { Thread(Runnable { try { Thread.sleep(delayed) } catch (e: InterruptedException) { e.printStackTrace() } post { startVerticalAnimate(duration) } }).start() } /** * start loop animate */ fun startHorizontalAnimate() { isPlaying = true invalidate() } /** * stop the loop animate */ fun stopAnimate() { isPlaying = false mLoopAnimateY = 0 invalidate() } companion object { //the touch mode var MODE_X = 0 var MODE_Y = 1 var MODE_BOTH_X_Y = 2 } init { //set a default background to make sure onDraw() dispatch if (background == null) { setBackgroundColor(Color.parseColor("#ffffff")) } var dm = DisplayMetrics() dm = resources.displayMetrics mDensity = dm.density mCamera = Camera() mMatrix = Matrix() }}
完整源代码
关注头条号,第一时间获取最新文章:
转载地址:https://cxyxy.blog.csdn.net/article/details/107410915 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月12日 23时39分18秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
K-means Algorithm 聚类算法
2019-04-30
Python拼接多张图片
2019-04-30
人脸识别数据集 FACE RECOGNITION DATABASES
2019-04-30
计算机视觉研究群体及专家主页汇总
2019-04-30
Labeled Faces in the Wild 人脸识别数据集
2019-04-30
人脸识别数据集 Face Databases
2019-04-30
AR Face Database 人脸识别数据集
2019-04-30
Database: Faces & Sketchs 人脸识别数据集
2019-04-30
ORL Face Database 人脸识别数据集
2019-04-30
The CIFAR-10 dataset 数据集
2019-04-30
ConvNetJS CIFAR-10 demo 卷积神经网络分类demo
2019-04-30
Corel-1000 dataset Wang 数据集
2019-04-30
CVonline: Image Databases 计算机视觉图像数据集
2019-04-30
使用HttpClient实现一个简单爬虫,抓取煎蛋妹子图
2019-04-30
用Python爬虫抓取煎蛋(jandan.net)无聊图和妹子图
2019-04-30
手把手教你用Python爬虫煎蛋妹纸海量图片
2019-04-30
windows中遍历指定文件夹下的所有子文件夹
2019-04-30
计算机视觉和模式识别领域SCI期刊介绍
2019-04-30