欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android仿即刻点赞文字部分的自定义View的示例代码

程序员文章站 2023-11-24 18:55:10
概述:在学习hencoder的过程中,有一期是模仿优秀自定义view,有一个项目是仿即刻的点赞,后来原作者在点评中提到,需要将文字和图片分开来写,并且模仿者的动画实现由点杂...

概述:在学习hencoder的过程中,有一期是模仿优秀自定义view,有一个项目是仿即刻的点赞,后来原作者在点评中提到,需要将文字和图片分开来写,并且模仿者的动画实现由点杂乱。所以决定重现实现下文字部分的效果。并拓展了更多功能。最后说一句本文基于kotlin实现。不明白的地方请在评论区指出。

即刻原效果:android仿即刻点赞文字部分的自定义View的示例代码个人效果:android仿即刻点赞文字部分的自定义View的示例代码

分析

从效果图容易看出,图中的功能主要分为两个部分:

  1. 左侧大拇指动画
  2. 右侧的文字动画

拓展的功能包括:文字变换模式(全部和部分) 改变文字和未改变文字的间隔和颜色,文字始终位于中心位置。

一 文字的绘制

对文字绘制还不熟悉的同学请参考hencoder系列文章,这里只对怎么实现居中的作一下说明。

1 水平居中

水平居中的绘制按文字变换模式分为两种

全部改变时:

控件宽度的一半减去文字宽度的一半 即是文字开始绘制的位置

canvas.drawtext(array[1], width / 2.tofloat() - halftextwidth(array[1]), baseliney + yoffset, mpaint)
canvas.drawtext(array[2], width / 2.tofloat() - halftextwidth(array[2]), baseliney + height / 2 + +halfoftextheight + yoffset, mpaint)

部分改变时

计算每部分文字起始位置

 // 获取部分改变的模式时的绘制文字其实起始位置
 startx = width / 2.tofloat() - (2 * halftextwidth(array[0]) + mtextspace + 2 * halftextwidth(array[1])) / 2

mpaint.color = mnochangetextcolor
canvas.drawtext(array[0], startx, baseliney, mpaint)

 mpaint.color = mchangedtextcolor
canvas.drawtext(array[1], startx + 2 * halftextwidth(array[0]) + mtextspace, baseliney + yoffset, mpaint)
canvas.drawtext(array[2], startx + 2 * halftextwidth(array[0]) + mtextspace, baseliney + height / 2 + +halfoftextheight + yoffset, mpaint)

2 垂直居中

垂直居中的实现,最重要的是需要计算文字基线在垂直方向的位置 计算公式就不在这里解释了

 var fontmetrics = mpaint.fontmetrics
// 文字基线y轴坐标 为了 让文字 垂直居中
val baseliney = height / 2 - fontmetrics.top / 2 - fontmetrics.bottom / 2

二 动画的实现

可以看到 我们默认是没有点赞的,然后点一下就赞,再点一下 取消点赞。所以思路是这样的 首先绘制居中文字,然后在控件看不到的下方再绘制一遍,然后根据平移动画完成这个效果,这个动画是通过属性动画实现的。

 // 为了显示效果 根据是否是全部改变 设置不同的绘制方式

if (mchangemode === 0) {

mpaint.color = mchangedtextcolor

canvas.drawtext(array[1], width / 2.tofloat() - halftextwidth(array[1]), baseliney + yoffset, mpaint)
canvas.drawtext(array[2], width / 2.tofloat() - halftextwidth(array[2]), baseliney + height / 2 + +halfoftextheight + yoffset, mpaint)

} else if (mchangemode === 1) {

/ 获取部分改变的模式时的绘制文字其实起始位置
startx = width / 2.tofloat() - (2 * halftextwidth(array[0]) + mtextspace + 2 * halftextwidth(array[1])) / 2

mpaint.color = mnochangetextcolor
canvas.drawtext(array[0], startx, baseliney, mpaint)
mpaint.color = mchangedtextcolor
canvas.drawtext(array[1], startx + 2 * halftextwidth(array[0]) + mtextspace, baseliney + yoffset, mpaint)
canvas.drawtext(array[2], startx + 2 * halftextwidth(array[0]) + mtextspace, baseliney + height / 2 + +halfoftextheight + yoffset, mpaint)
    }

可以看到 在设置绘制垂直方向的位置的时候,都加入了一个 yoffset 的变量,通过改变这个属性的值也显示动画,那个这个值的最大值很明显就是 文字高度的一半加上控件高度的一半。

halfoftextheight = (fontmetrics.bottom - fontmetrics.top) / 2
textoffset = (halfoftextheight + height / 2)

自定义属性动画必须添加的 set get 方法

 @suppress("unused")
 fun setyoffset(yoffset: float) {
    this.yoffset = yoffset
    invalidate()
 }

 @suppress("unused")
 fun getyoffset() = yoffset

 最后提供给外界跳用的方法

  fun show() {

    hasthumbs = if (hasthumbs) {
      val animator = objectanimator.offloat(this, "yoffset", -textoffset, 0f)
      animator.duration = 500
      animator.start()
      false
    } else {
      val animator = objectanimator.offloat(this, "yoffset", 0f, -textoffset)
      animator.duration = 500
      animator.start()
      true
    }
  }
 // 调用
 val tv: thumbsview = findviewbyid(r.id.thumbsview1) as thumbsview
 tv.show()
 

三 源码

github地址:源码点我直达

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。