带有立体纵深的卡片翻页效果,稍加组合和颜色变化就可以搭配出多种不同的风格,如:
比赛比分牌
卡片翻页时钟
一、设计思路
如何使得数字的变化更为灵动?3D纵深效果是个值得思考的方案。在现实生活中的一些特定场景,数字的变化就是通过翻页实现的,比如日历、比分牌、数学教具等等。
灵活替换翻页卡片的颜色和数字图片,即可展现多种不同风格
二、实现方案
2.1 3D纵深效果实现方案参考
为了在Android上实现3D纵深效果,可以考虑使用OpenGL进行,这样实现的效果是细节最丰富、最拟物的,但成本也巨大,为了一个控件使用OpenGL实在是用核弹打苍蝇——可以但没必要。
这里考虑采用Matrix+Camera结合的方案。
2.2 Matrix简介
android中的matrix是一个3*3的矩阵,如下图
scale控制缩放,skew控制错切,trans控制位移,persp控制透视,值得注意的是,旋转操作是通过scale和skew共同作用完成的。
android中matix的封装非常完善,使用者无需再去重拾体育老师教授的数学知识,直接调用。
2.3 Camera简介
这里指的是android.graphics包下的Camera,用于计算3D变换。封装得同样十分完善,使用者无需再用屁股思考控件坐标计算过程,直接调用,同时搭配好对应的matrix。
需要注意的是,Camera中摄像头的位置是对准画布左上角的。
坐标系如下,是左手坐标系:
常用方法如下:
2.4 UI拆解
**2.4.1 形状分析**
从形状上观察并不复杂,算上正在翻转的卡片,3个圆角矩形即可搞定。数字部分采用图片绘制,可以灵活替换,最后在指定卡片区域绘制图片即可。
**2.4.2 模型设计**
卡片翻转过程中,最多同一时刻出现3个卡片,故只需要按位置关系定义上中下三个卡片,中间的卡片负责翻转。
2.5 纵深效果实现
**2.5.1 卡片绘制**
绘制上中下卡片,中间卡片为活动页,需要最后绘制
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
setLayerType(LAYER_TYPE_SOFTWARE, null)
//判断状态,不同状态绘制不同内容
judgeState(curState)
canvas?.let {
drawUpCard(it)
drawDownCard(it)
// 中间活动card最后绘制
drawMidCard(it)
}
}
**2.5.2 实现卡片翻页**
中间卡片翻页效果通过Camera的roate方法实现,绕x轴进行旋转
private fun drawMidCard(canvas: Canvas) {
if (!isNeedDrawMidCard) return
with(canvas) {
save()
mMatrix.reset()
mCamera.save()
mCamera.translate(0F, 0F, depthZ)
mCamera.rotateX(rotateX)
mCamera.rotateY(rotateY)
mCamera.getMatrix(mMatrix)
mCamera.restore()
val scale = resources.displayMetrics.density
val mValues = FloatArray(9)
mMatrix.getValues(mValues)
mValues[6] = mValues[6] / scale
mValues[7] = mValues[7] / scale
mMatrix.setValues(mValues)
mMatrix.preTranslate(-width / 2F, -height / 2F)
mMatrix.postTranslate(width / 2F, height / 2F)
concat(mMatrix)
mPaint.color = Color.WHITE
mPaint.setShadowLayer(cardShadowSize, 0F, cardShadowDistance, Color.GRAY)
val rectF = RectF(paddingSize, paddingSize + cardHeight, paddingSize + cardWidth, paddingSize + cardHeight * 2)
drawRoundRect(
rectF,
20F,
20F,
mPaint
)
//todo: 绘制数字图片
restore()
}
}
结合我在[《今日头条loading控件,隔壁产品都馋哭了》]( )文章中提到过的坐标计算框架,用户手指在屏幕上移动的距离与中间卡片旋转角度存在某种函数关系,通过IFunc进行保存和计算。
代码如下:
/**
- Card翻转函数
/
var cardRotateFunc: IFunc? = null
/* - 阴影大小变化函数
/
var cardShadowSizeFunc: IFunc? = null
/* - 阴影距离变化函数
/
var cardShadowDistanceFunc: IFunc? = null
/* - 配置各个函数
*/
private fun configFunc() {
cardRotateFunc = CardRotateFunc()
with(cardRotateFunc!!) {
inParamMin = 0F
inParamMax = cardHeight * 2
outParamMin = 0F
outParamMax = 180F
initValue = 45F
}
cardShadowSizeFunc = CardShadowSizeFunc()
with(cardShadowSizeFunc!!) {
inParamMin = 0F
inParamMax = 180F
outParamMax = 50F
outParamMin = 0F
initValue = 10F
}
cardShadowDistanceFunc = CardShadowDistanceFunc()
with(cardShadowDistanceFunc!!) {
inParamMin = 0F
inParamMax = 180F
outParamMax = 50F
outParamMin = 0F
initValue = 10F
}
}
**2.5.3 阴影变化**
为了更好地模拟3D效果,卡片阴影也存在微小的变化
/**
- 根据旋转角度计算阴影大小、距离
*/
private fun executeShadowFunc(rotate: Float) {
cardShadowSizeFunc?.let {
cardShadowSize = it.execute(rotate)
}
cardShadowDistanceFunc?.let {
cardShadowDistance = it.execute(rotate)
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
总结
可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:
❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞
希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。
下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。
**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)
点击这里了解更多即可领取!
- Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)
- Flutter进阶学习全套手册
- Flutter进阶学习全套视频
可领取!
- Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)
[外链图片转存中…(img-jV1yYKMd-1711101959306)]
- Flutter进阶学习全套手册
[外链图片转存中…(img-2futFUjI-1711101959306)]
- Flutter进阶学习全套视频
[外链图片转存中…(img-OJECpRZc-1711101959307)]
大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。