【一步教学,一步到位,flutter切换页面不刷新

}
}

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()
}
}
image

结合我在《今日头条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)
    }
    }
    复制代码

2.5.4 数字图片绘制

数字的绘制就是图片的绘制,需要注意的是中间活动卡片在上翻或下翻转超过90度时,绘制的数字需要改变,涉及到图片的水平镜像翻转,调用matrix.postScale(-1F, 1F)实现。以下翻为例,代码如下:

if (curState == STATE_DOWN_ING) {
//往下翻
if (abs(cardRotateFunc!!.initValue - rotateX) >= 90F) {
//绘制前一个数字
if (curShowNum - 1 >= 0) {
tempBm = Bitmap.createBitmap(numBms[curShowNum - 1], 0, 0, curNumBm.width, curNumBm.height, matrix, false)
} else {
tempBm = Bitmap.createBitmap(numBms[0], 0, 0, curNumBm.width, curNumBm.height, matrix, false)
}
} else {
tempBm = Bitmap.createBitmap(numBms[curShowNum], 0, 0, curNumBm.width, curNumBm.height, matrix, false)
}
}
tempBm?.let {
drawBitmap(it, Rect(0, it.height / 2, it.width, it.height), rectF, mPaint)
}
复制代码

2.6 实现交互

2.6.1 上下翻转

逻辑主要在onTouchEvent方法中,通过中间卡片初始角度和当前的翻转角度判断是上翻还是下翻

/**

  • 手指按下的初始坐标
    */
    private var downX: Float = 0F
    private var downY: Float = 0F
    private var offsetY: Float = 0F
    override fun onTouchEvent(event: MotionEvent?): Boolean {
    when (event?.action) {
    MotionEvent.ACTION_DOWN -> {
    downX = event.x
    downY = event.y
    if (downY >= height / 2) {
    //绘制下方的mid card
    rotateX = 0F
    curState = STATE_UP_ING
    } else {
    rotateX = 180F
    curState = STATE_DOWN_ING
    }
    resetInitValue()
    postInvalidate()
    }
    MotionEvent.ACTION_MOVE -> {
    offsetY = event.y - downY
    executeFunc(offsetY)
    postInvalidate()
    }
    MotionEvent.ACTION_UP -> {
    //判断是上翻还是下翻
    if (rotateX >= 90F) {
    if (abs(cardRotateFunc!!.initValue - rotateX) >= 90F) {
    if (curShowNum + 1 <= 9) {
    startCardUpAnim(curShowNum + 1)
    } else {
    curShowNum = 9
    startCardDownAnim(9)
    }
    } else {
    startCardUpAnim(curShowNum)
    }
    } else {
    if (abs(cardRotateFunc!!.initValue - rotateX) >= 90F) {
    if (curShowNum - 1 >= 0) {
    startCardDownAnim(curShowNum - 1)
    } else {
    curShowNum = 0
    startCardUpAnim(0)
    }
    } else {
    startCardDownAnim(curShowNum)
    }
    }
    downX = 0F
    downY = 0F
    }

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

**一个零基础的新人,我认为坚持是最最重要的。**我的很多朋友都找我来学习过,我也很用心的教他们,可是不到一个月就坚持不下来了。我认为他们坚持不下来有两点主要原因:

他们打算入行不是因为兴趣,而是因为所谓的IT行业工资高,或者说完全对未来没有任何规划。

刚开始学的时候确实很枯燥,这确实对你是个考验,所以说坚持下来也很不容易,但是如果你有兴趣就不会认为这是累,不会认为这很枯燥,总之还是贵在坚持。

技术提升遇到瓶颈了?缺高级Android进阶视频学习提升自己吗?还有大量大厂面试题为你面试做准备!

提升自己去挑战一下BAT面试难关吧

对于很多Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些知识图谱希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

不论遇到什么困难,都不应该成为我们放弃的理由!

如果有什么疑问的可以直接私我,我尽自己最大力量帮助你!

最后祝各位新人都能坚持下来,学有所成。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
读者们能谨记这一点。

不论遇到什么困难,都不应该成为我们放弃的理由!

如果有什么疑问的可以直接私我,我尽自己最大力量帮助你!

最后祝各位新人都能坚持下来,学有所成。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-xRVgGkJx-1712792994411)]

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值