面试跳槽原因怎么说,高级UI强行进阶,秀出天际

这篇具有很好参考价值的文章主要介绍了面试跳槽原因怎么说,高级UI强行进阶,秀出天际。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

lateinit var rotateAnimator: ObjectAnimator

override fun onCreate(savedInstanceState: Bundle?) {

setContentView(demoBinding.root)

rotateAnimator = ObjectAnimator.ofFloat(demoBinding.musicAvatar, View.ROTATION, 0f, 360f)

rotateAnimator.duration = 6000

rotateAnimator.repeatCount = -1

rotateAnimator.interpolator = LinearInterpolator()

lifecycleScope.launch(Dispatchers.Main) {

loadImage()

//添加点击事件,并且启动动画

demoBinding.musicAvatar.setOnClickListener {

rotateAnimator.start()

}

}

}

这些都是小儿科了,相信面对电视机前的观众朋友们,啊不,口误口误。

相信小伙伴们都很熟悉了,那我们开始今天的重头戏,这个粒子动画。

粒子动画


其实我很久以前看粒子动画的时候,也很好奇,这些炫酷的粒子动画是怎么实现的,当时的我完全没有思路。

尤其是看到一些图片,啪唧一下变成了一堆粒子,掉落,然后又呱唧从粒子变成了图片,就觉得异常的牛X。

其实啊,一点都不神奇。

首先我们要知道bitmap是什么。bitmap是什么呀?

在数学上,有这么几个概念,点,线,面。点很好理解,就是一个点。线是由一堆点组成的,而面又类似于一堆线组成的。本质上,面就是由无数的点组成的。

可是这和bitmap以及今天的粒子动画有什么关系呢?

一个bitmap,我们可以简单地理解为一张图片。这个图片是不是一个平面呢?而平面又是一堆点组成的,这个点在这里称为像素点。所以bitmap就是由一堆像素点所组成的,有趣的是,这些像素点是有颜色的,当这些像素点足够小,你离得足够远你看起来就像一幅完整的画了。

在现实中也不乏这样的例子,举办一些活动的时候,一个个人穿着不同颜色的衣服有序的站在广场上,如果有一架无人机在空中看,就能看到是一幅画。就像这样

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

所以当把一幅画拆成一堆粒子的话,其实就是获得bitmap中所有的像素点,然后改变他们的位置就可以了。如果想要用一堆粒子拼凑出一幅画,只需要知道这些粒子的顺序,排放整齐自然就是一幅画了。

扯远了,说这些呢其实和今天的效果没有特别强的联系,只是为了让你能够更好的理解粒子动画的本质。

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

粒子动画分析

我们先观察这个特效,你会发现有一个圆,这个圆上不断的往外发散粒子,粒子在发散的过程中速度是不相同的。而且,在发散的过程中,透明度也在不断变化,直到最后完全透明。

好,我们归纳一下。

  • 圆形生产粒子

  • 粒子速度不同,也就是随机。

  • 粒子透明度不断降低,直到最后消散。

  • 粒子沿着到圆心的反方向扩散。

写自定义View的时候千万不要一上来就开干,而是要逐渐分析,有的时候我们遇到一个复杂的效果,更是要逐帧的分析。

而且我写自定义View的时候有个习惯,就是一点点的实现效果,不会去一次性实现全部的效果。

所以我们第一步,生产粒子。

生产粒子

首先,我们可以知道,粒子是有颜色的,但是似乎这个效果粒子只有白色,那就指定粒子颜色为白色了。

然后我们可以得出,粒子是有位置的,位置肯定由x,y组成嘛。然后粒子还有个速度,以及透明度和半径。

定义粒子

我们可以定义一个粒子类:

class Particle(

var x:Float,//X坐标

var y:Float,//Y坐标

var radius:Float,//半径

var speed:Float,//速度

var alpha: Int//透明度

)

由于我们的这个效果看起来就像是水波一样的涟漪,我给自定义View起名为涟漪,也就是dimple

我们来定义这个自定义View把

定义自定义view

class DimpleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {

//定义一个粒子的集合

private var particleList = mutableListOf()

//定义画笔

var paint = Paint()

}

一开始就直接圆形生产粒子着实有些难度,我先考虑考虑如何实现生产粒子把。

先不断生产粒子,然后再考虑圆形的事情。

而且生产一堆粒子比较麻烦,我先实现从上到下生产一个粒子。

那么如何生产一个粒子呢?前面也说了,粒子就是个很小的点,所以用canvas的drawCircle就可以。

那我们来吧

override fun onDraw(canvas: Canvas) {

super.onDraw(canvas)

paint.color = Color.WHITE

paint.isAntiAlias = true

var particle=Particle(0f,0f,2f,2f,100)

canvas.drawCircle(particle.x, particle.y, particle.radius, paint)

}

画画嘛,就要在onDraw方法中进行了。我们先new一个Particle,然后画出来。

实际上这样并没有什么效果。为啥呢?

我们的背景是白色的,粒子默认是白色的,你当然看不到了。所以我们需要先做个测试,为了能看出效果。这里啊,我们把背景换成黑色。同时,为了方便测试,先把Imageview设置成不可见。然后我们看下效果

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

没错,就是没什么效果。你什么都看不出来。

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

先不急,慢慢来,且听我吹,啊不,且听我和你慢慢道来。

我们在这里只花了一个圆,而且是在坐标原点画了一个半径为2的点,可以说很小很小了。自然就看不到了。

什么,你不知道原点在哪?

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

棕色部分就是我们的屏幕,所以原点就是左上角。

现在我们需要做的事情只有两个,要么把点变大,要么改变点的位置。

粒子粒子的,当然不能变大,所以我们把它放到屏幕中心去。

所以我们定义一个屏幕中心的坐标,centerX,centerY。并且在onSizeChanged方法中给它们赋值

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {

super.onSizeChanged(w, h, oldw, oldh)

centerX= (w/2).toFloat()

centerY= (h/2).toFloat()

}

那我们改一下上面的画点的代码:

override fun onDraw(canvas: Canvas) {

var particle=Particle(centerX,centerY,2f,2f,100)

canvas.drawCircle(particle.x, particle.y, particle.radius, paint)

}

如此,可以看到这个点了,虽然很小很小,但是也胜过没有呀

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

可是这时候有人跳出来了,说你这不对啊,一个点有啥用?还那么小,我本来就近视,你这搞得我更看不清了。你是不是眼睛店派来的叛徒!

添加多个粒子

那好吧,我们多加几个。可是该怎么加?效果图中是圆形的,可是我不会啊,我只能先试试一横排添加。看看这样可不可以呢?我们知道,横排的话就是y值不变,x变。好,但是为了避免我们画出一条线,我们x值随机增加,这样的话看起来也比较不规则一些。

那么代码就应该是这样了

override fun onDraw(canvas: Canvas) {

super.onDraw(canvas)

paint.color = Color.WHITE

paint.isAntiAlias = true

for (i in 0…50){

var random= Random()

var nextX=random.nextInt((centerX*2).toInt())

var particle=Particle(nextX.toFloat(),centerY,2f,2f,100)

canvas.drawCircle(particle.x, particle.y, particle.radius, paint)

}

}

由于centerX是屏幕的中心,所以它的值是屏幕宽度的一半,这里的话X的值就是在屏幕宽度内随机选一个值。那么效果看起来是下面这样

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

效果看起来不错了。

但是总有爱搞事的小伙伴又跳出来了,说你会不会写代码?onDraw方法一直被调用,不能定义对象你不知道么?很容易引发频繁的GC,造成内存抖动的。而且你这还搞个循环,性能能行不?

这个小伙伴你说的非常对,是我错了!

确实,在ondraw方法中不适合定义对象,尤其是for循环中就更不能了。段时间看,我们50个粒子好像对性能的开销不是很大,但是一旦粒子数量很多,性能开销就会十分的大。而且,为了不掉帧,我们需要在16ms之内完成绘制。这个不明白的话我后续会有性能优化的专题,可以关注一下我~

这里我们测量一下50个粒子的绘制时间和5000个粒子的绘制时间。

override fun onDraw(canvas: Canvas) {

super.onDraw(canvas)

paint.color = Color.WHITE

paint.isAntiAlias = true

var time= measureTimeMillis {

for (i in 0…50){

var random= Random()

var nextX=random.nextInt((centerX*2).toInt())

var particle=Particle(nextX.toFloat(),centerY,2f,2f,100)

canvas.drawCircle(particle.x, particle.y, particle.radius, paint)

}

}

Log.i(“dimple”,“绘制时间$time ms”)

}

结果如下:50个粒子的绘制时间

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

5000个粒子的绘制时间:

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

可以看到,明显超了16ms。所以我们需要优化,怎么优化?很简单,就是不在ondraw方法中创建对象就好了,那我们选择在哪里呢?

构造方法可以吗?好像不可以呢,这个时候还没办法获得屏幕宽高,嘿嘿嘿,onSizeChanged方法就决定是你了!

粒子添加到集合中

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {

super.onSizeChanged(w, h, oldw, oldh)

centerX= (w/2).toFloat()

centerY= (h/2).toFloat()

val random= Random()

var nextX=0

for (i in 0…5000){

nextX=random.nextInt((centerX*2).toInt())

particleList.add(Particle(nextX.toFloat(),centerY,2f,2f,100))

}

}

我们再来看看onDraw方法中绘制时间是多少:

override fun onDraw(canvas: Canvas) {

super.onDraw(canvas)

paint.color = Color.WHITE

paint.isAntiAlias = true

var time= measureTimeMillis {

particleList.forEach {

canvas.drawCircle(it.x,it.y,it.radius,paint)

}

}

Log.i(“dimple”,“绘制时间$time ms”)

}

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

emmmm,好像是低于16ms了,可是这也太危险了吧,你这分分钟就超过了16ms啊。

确实是这样子,但是实际情况下,我们并不需要5000个这么多的粒子。又有人问,,万一真的需要怎么办?那就得看surfaceView了。这里就不讲了

我们还是回过头来,先把粒子数量变成50个。

现在粒子也有了,该实现动起来的效果了。

动起来,我们想想,应该怎么做呢?效果图是类似圆一样的扩散,我现在做不到,我往下掉这应该不难吧?

说动就动,搞起!至于怎么动,那肯定是属性动画呀。

定义动画

private var animator = ValueAnimator.ofFloat(0f, 1f)

init {

animator.duration = 2000

animator.repeatCount = -1

animator.interpolator = LinearInterpolator()

animator.addUpdateListener {

updateParticle(it.animatedValue as Float)

invalidate()//重绘界面

}

}

我在这里啊,定义了一个方法updateParticle,每次动画更新的时候啊就去更新粒子的状态。

updateParticle方法应该去做什么事情呢?我们来开动小脑筋想想。

如果说是粒子不断往下掉的话,那应该是y值不断地增加就可以了,嗯,非常有道理。

我们来实现一下这个方法

更新粒子位置

private fun updateParticle(value: Float) {

particleList.forEach {

it.y += it.speed

}

}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {

animator.start()//别忘了启动动画

}

那我们现在来看一下效果如何

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

emmmm看起来有点雏形了,不过效果图里的粒子速度似乎是随机的,咱们这里是同步的呀。

没关系,我们可以让粒子的速度变成随机的速度。我们修改添加粒子这里的代码

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {

super.onSizeChanged(w, h, oldw, oldh)

centerX = (w / 2).toFloat()

centerY = (h / 2).toFloat()

val random = Random()

var nextX = 0

var speed=0 //定义一个速度

for (i in 0…50) {

nextX = random.nextInt((centerX * 2).toInt())

speed= random.nextInt(10)+5 //速度从5-15不等

particleList.add(

Particle(nextX.toFloat(), centerY, 2f, speed.toFloat(), 100)

)

}

animator.start()

}

这是效果,看起来有点样子了。不过问题又来了,人家的粒子是一直散发的,你这个粒子怎么没了就是没了呢?

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

有道理,所以我觉得我们需要设置一个粒子移动的最大距离,一旦超出这个最大距离,我们啊就让它回到初始的位置。

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

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

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

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

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

最后

希望本文对你有所启发,有任何面试上的建议也欢迎留言分享给大家。

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

好了~如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

面试跳槽原因怎么说,高级UI强行进阶,秀出天际,2024年程序员学习,跳槽,ui

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算文章来源地址https://www.toymoban.com/news/detail-847499.html

分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

[外链图片转存中…(img-bE6XZ7SG-1712573110168)]

好了~如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

[外链图片转存中…(img-LYitWaVB-1712573110168)]

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

到了这里,关于面试跳槽原因怎么说,高级UI强行进阶,秀出天际的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android-高级-UI-进阶之路(四)-Paint-渲染-滤镜-xfermode-使用

    class MyGradientView : View { private var mPaint: Paint? = null private var mBitMap: Bitmap? = null private var mWidth: Int = 0 private var mHeight: Int = 0 private val mColors = intArrayOf(Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW) constructor(context: Context?) : super(context) { init() } constructor(context: Context?, attrs: AttributeSet?) : super(

    2024年04月16日
    浏览(43)
  • Android-高级-UI-进阶之路-(七)-SVG-基础使用-+-绘制中国地图

    输入搜索动画 利用在线绘制 SVG 图标网站 制作搜索图标 可以自己随意捣鼓绘制,绘制好了之后点击视图-源代码,将 SVG 代码复制出来保存成 search_svg.xml 在线转换 svg2vector 点击空白或者直接将 SVG 拖拽指定区域进行转换 将转换好的 Android 格式的 vector 导入 AS 开始制作动画关联

    2024年03月20日
    浏览(54)
  • Android高级UI进阶之路(七)——SVG基础使用(绘制中国地图)

    Android高级UI进阶之路(一) —— View的基础知识 Android高级UI进阶之路(二) —— 深入理解Android8.0 View的触摸事件分发机制 Android高级UI进阶之路(三) —— 理解View的工作原理及自定义View入门 Android高级UI进阶之路(四) —— Paint渲染滤镜xfermode使用 Android高级UI进阶之路(五) —— Canva

    2024年02月05日
    浏览(38)
  • 【转载】Win10系统, administrator账户被微软账户强行绑定,怎么破?

    声明:这是转载,我只是做一个记录,以下内容可解决问题(本人已尝试并已解决),当然也可以去转载出处查看大佬的原回答: Win10系统, administrator账户被微软账户强行绑定,怎么破? - 海尔森肯威的回答 - 知乎 因为要修改注册表,为了安全起见最好还是先备份一下!

    2024年02月13日
    浏览(58)
  • Android-高级-UI-进阶之路-(五)-看完该篇文章-Canvas-你应该会了

    /** 1. 绘制椭圆 */ canvas.drawOval(RectF(100f,500f,600f,800f),mPaint) /** 2. 绘制圆 */ mPaint.setColor(Color.YELLOW) mPaint.alpha = 100 canvas.drawCircle(400f,400f,200f,mPaint) 绘制 Bitmap // val bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.gild_3) //第二个,第三个参数代表起点位置 canvas.drawBitmap(bitmap,100f,100

    2024年03月28日
    浏览(54)
  • 4月跳槽进字节跳动了,面试真简单...

    最近金三银四跳槽季,相信很多小伙伴都在面试找工作, 怎样才能拿到大厂的offer,没有掌握绝对的技术,那么就要不断的学习 ,没有绝对的天才,只有持续不断的付出。对于我们每一个平凡人来说,改变命运只能依靠努力+幸运,但如果你不够幸运,那就只能拉高努力的占

    2024年02月03日
    浏览(42)
  • 【跳槽面试】谈谈联合索引生效和失效的条件

    这道题考查索引生效条件、失效条件。像这类问题才其实很有意义,建议各位以后面试其他伙伴的时候,多侧重这类问题的提问,比考察一般概念性的问题好多了。 能大概考察应聘者对写的程序是有注重做优化,提高代码质量和程序性能呢 还是只简单的CV了事。 联合索引又

    2024年01月20日
    浏览(37)
  • 【跳槽面试】一份tcp、http面试指南,常考点都给你了

    要说http就绕不开tcp,TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性。但是,http是基于tcp协议的。 TCP/IP 协议分层模型 物理层将二进制的0和1和电压高低,光的闪灭和电波的强弱信号进行转换 链路层代表驱动 网络层 使用 IP 协议,IP 协议基于

    2024年01月23日
    浏览(64)
  • Canvas中的裁剪师讲解与实战——Android高级UI(1),Android体系化进阶学习图谱

    从今天开始我们聊一聊 Canvas 的API,因为Canvas的API较多,所以我们分为几次分享,首先分享的是裁剪类型的API使用。话不多说,先上实战图。 老夫的少女心 源码地址文末会给出,了解原理才能更好地驾驭。 分享前,我们先来聊聊,在我们生活中如何绘制一张如下的图。 我们

    2024年04月13日
    浏览(86)
  • Android-高级-UI-进阶之路-(二)-深入理解-Android-8-0-View-触摸事件分发机制,查漏补缺

    我们看到内部又调用了父类 dispatchTouchEvent 方法, 所以最终是交给 ViewGroup 顶级 View 来处理分发了。 顶级 View 对点击事件的分发过程 在上一小节中我们知道了一个事件的传递流程,这里我们就大致在回顾一下。首先点击事件到达顶级 ViewGroup 之后,会调用自身的 dispatchTouchE

    2024年04月14日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包