Android自定义View模仿即刻点赞数字切换效果实例

目录
  • 即刻点赞展示
  • 自己如何实现这种数字切换呢?
    • 效果展示
    • 源码
  • 总结

即刻点赞展示

点赞的数字增加和减少并不是整个替换,而是差异化替换。再加上动画效果就看的很舒服。

自己如何实现这种数字切换呢?

下面用一张图来展示我的思路:

现在只需要根据这张图,写出对应的动画即可。 分为2种场景:

  • 数字+1:

    • 差异化的数字从3号区域由渐变动画(透明度 0- 255) + 偏移动画 (3号区域绘制文字的基线,2号区域绘制文字的基线),将数字移动到2号位置处
    • 差异化的数字从2号区域由渐变动画(透明度 255- 0) + 偏移动画(2号区域绘制文字的基线,1号区域绘制文字的基线),将数字移动到1号位置处
  • 数字-1
    • 差异化的数字从1号区域由渐变动画(透明度 0- 255) + 偏移动画 (1号区域绘制文字的基线,2号区域绘制文字的基线),将数字移动到2号位置处
    • 差异化的数字从2号区域由渐变动画(透明度 255- 0) + 偏移动画(2号区域绘制文字的基线,3号区域绘制文字的基线),将数字移动到3号位置处

公共部分就是: 不变的文字不需要做任何处理,绘制在2号区域就行。绘制差异化文字时,需要加上不变的文字的宽度就行。

效果展示

源码

class LikeView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().also {
        it.isAntiAlias = true
        it.textSize = 200f
    }

    private val textRect0 = Rect(300, 100, 800, 300)
    private val textRect1 = Rect(300, 300, 800, 500)
    private val textRect2 = Rect(300, 500, 800, 700)

    private var nextNumberAlpha: Int = 0
        set(value) {
            field = value
            invalidate()
        }

    private var currentNumberAlpha: Int = 255
        set(value) {
            field = value
            invalidate()
        }

    private var offsetPercent = 0f
        set(value) {
            field = value
            invalidate()
        }

    private val fontMetrics: FontMetrics = paint.fontMetrics
    private var currentNumber = 99
    private var nextNumber = 0
    private var motionLess = currentNumber.toString()
    private var currentMotion = ""
    private var nextMotion = ""

    private val animator: ObjectAnimator by lazy {
        val nextNumberAlphaAnimator = PropertyValuesHolder.ofInt("nextNumberAlpha", 0, 255)
        val offsetPercentAnimator = PropertyValuesHolder.ofFloat("offsetPercent", 0f, 1f)
        val currentNumberAlphaAnimator = PropertyValuesHolder.ofInt("currentNumberAlpha", 255, 0)
        val animator = ObjectAnimator.ofPropertyValuesHolder(
            this,
            nextNumberAlphaAnimator,
            offsetPercentAnimator,
            currentNumberAlphaAnimator
        )
        animator.duration = 200
        animator.interpolator = DecelerateInterpolator()
        animator.addListener(
            onEnd = {
                currentNumber = nextNumber
            }
        )
        animator
    }

    override fun onDraw(canvas: Canvas) {
        paint.alpha = 255

        paint.color = Color.LTGRAY
        canvas.drawRect(textRect0, paint)

        paint.color = Color.RED
        canvas.drawRect(textRect1, paint)

        paint.color = Color.GREEN
        canvas.drawRect(textRect2, paint)

        paint.color = Color.BLACK
        if (motionLess.isNotEmpty()) {
            drawText(canvas, motionLess, textRect1, 0f)
        }

        if (nextMotion.isEmpty() || currentMotion.isEmpty()) {
            return
        }

        val textHorizontalOffset =
            if (motionLess.isNotEmpty()) paint.measureText(motionLess) else 0f
        if (nextNumber > currentNumber) {
            paint.alpha = currentNumberAlpha
            drawText(canvas, currentMotion, textRect1, textHorizontalOffset, -offsetPercent)
            paint.alpha = nextNumberAlpha
            drawText(canvas, nextMotion, textRect2, textHorizontalOffset, -offsetPercent)
        } else {
            paint.alpha = nextNumberAlpha
            drawText(canvas, nextMotion, textRect0, textHorizontalOffset, offsetPercent)
            paint.alpha = currentNumberAlpha
            drawText(canvas, currentMotion, textRect1, textHorizontalOffset, offsetPercent)
        }
    }

    private fun drawText(
        canvas: Canvas,
        text: String,
        rect: Rect,
        textHorizontalOffset: Float = 0f,
        offsetPercent: Float = 0f
    ) {
        canvas.drawText(
            text,
            rect.left.toFloat() + textHorizontalOffset,
            rect.top + (rect.bottom - rect.top) / 2f - (fontMetrics.bottom + fontMetrics.top) / 2f + offsetPercent * 200,
            paint
        )
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        animator.end()
    }

    fun plus() {
        if (currentNumber == Int.MAX_VALUE) {
            return
        }
        nextNumber = currentNumber + 1

        processText(findEqualsStringIndex())

        if (animator.isRunning) {
            return
        }
        animator.start()
    }

    fun minus() {
        if (currentNumber == 0) {
            return
        }
        nextNumber = currentNumber - 1
        processText(findEqualsStringIndex())
        if (animator.isRunning) {
            return
        }
        animator.start()
    }

    private fun findEqualsStringIndex(): Int {
        var equalIndex = -1
        val nextNumberStr = nextNumber.toString()
        val currentNumberStr = currentNumber.toString()

        val endIndex = min(currentNumberStr.length, nextNumberStr.length) - 1

        for (index in 0..endIndex) {
            if (nextNumberStr[index] != currentNumberStr[index]) {
                break
            }
            equalIndex = index
        }
        return equalIndex
    }

    private fun processText(index: Int) {
        val currentNumberStr = currentNumber.toString()
        val nextNumberStr = nextNumber.toString()
        if (index == -1) {
            motionLess = ""
            currentMotion = currentNumberStr
            nextMotion = nextNumberStr
        } else {
            motionLess = currentNumberStr.substring(0, index + 1)
            currentMotion = currentNumberStr.substring(index + 1)
            nextMotion = nextNumberStr.substring(index + 1)
        }
    }
}

总结

到此这篇关于Android自定义View模仿即刻点赞数字切换效果的文章就介绍到这了,更多相关Android模仿即刻点赞数字切换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android实现朋友圈点赞列表

    本文实例为大家分享了Android朋友圈点赞列表的具体代码,供大家参考,具体内容如下 Android实现朋友圈评论回复列表 Android实现朋友圈点赞列表 Android实现朋友圈多图显示功能 正文 效果图: 具体实现代码 LikesView public class LikesView extends TextView { private Context mContext; private List<UserBean> list; public LikesView(Context cont

  • Android仿微信朋友圈点赞和评论功能

    最近在做朋友圈的项目,所以写一个Android仿朋友圈点赞和评论功能Demo,代码就是简单实现了一下功能,没有做优化,凑合看 图文排列是用的RecyclerView实现的,弹窗效果是用的自定义的PopupWindow,点赞应该是在本地请求数据库,设置一个flag,获取当前用户的id后,带着id向服务器post一个flag,评论就比较简单了,也是获取当前朋友id(或者昵称),带着内容,向服务器post 贴代码: package com.example.lenovo.dianzandemo; imp

  • android实现直播点赞飘心动画效果

    前段时间在写直播的时候,需要观众在看直播的时候点赞的效果,在此参照了腾讯大神写的点赞(飘心动画效果).下面是效果图: 1.自定义飘心动画的属性 在attrs.xml 中增加自定义的属性 <!-- 飘心动画自定义的属性 --> <declare-styleable name="HeartLayout"> <attr name="initX" format="dimension"/> <attr name=&

  • Android中Listview点赞功能的实现

    最近这段时间一直在看Android,利用Listview去实现点赞功能,下面给大家介绍下基本思路. 基本思路: 进入界面–>获取数据–> 在Listview中显示–> 通过map集合(position,boolean)保存每一行是否被点击–> 利用实体类去保存相应的对象–> get/set方法进行相应值得改变–> 点击一次,相应的数量加1 只实现了点赞功能,踩和赞基本类似. 具体实现如下: 继承自BaseAdapter package com.gz.test_listv

  • Android 仿微信朋友圈点赞和评论弹出框功能

    贡献/下载源码:https://github.com/mmlovesyy/PopupWindowDemo 本文简单模仿微信朋友圈的点赞和评论弹出框,布局等细节请忽略,着重实现弹出框.发评论,及弹出位置的控制. 1. 微信弹出框 微信朋友圈的点赞和评论功能,有2个组成部分: 点击左下角的"更多"按钮,弹出对话框: 点击评论,弹出输入框,添加评论并在页面中实时显示: 微信朋友圈点赞和评论功能 2. 实际效果 本文将建一个 ListView,在其 Item 中简单模仿微信的布局,然后着重实现

  • Android自定义view实现仿抖音点赞效果

    前言 学习自定义view,想找点东西耍一下,刚好看到抖音的点赞效果不错,尝试一下. 抖音效果: 话不多说,先上代码: public class Love extends RelativeLayout { private Context mContext; float[] num = {-30, -20, 0, 20, 30};//随机心形图片角度 public Love(Context context) { super(context); initView(context); } public

  • Android自定义View模仿即刻点赞数字切换效果实例

    目录 即刻点赞展示 自己如何实现这种数字切换呢? 效果展示 源码 总结 即刻点赞展示 点赞的数字增加和减少并不是整个替换,而是差异化替换.再加上动画效果就看的很舒服. 自己如何实现这种数字切换呢? 下面用一张图来展示我的思路: 现在只需要根据这张图,写出对应的动画即可. 分为2种场景: 数字+1: 差异化的数字从3号区域由渐变动画(透明度 0- 255) + 偏移动画 (3号区域绘制文字的基线,2号区域绘制文字的基线),将数字移动到2号位置处 差异化的数字从2号区域由渐变动画(透明度 255-

  • Android 自定义view实现进度条加载效果实例代码

    这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

  • Android自定义View模仿QQ讨论组头像效果

    首先来看看我们模仿的效果图,相信对于使用过QQ的人来说都不陌生,效果图如下: 在以前的一个项目中,需要实现类似QQ讨论组头像的控件,只是头像数量和布局有一小点不一样:一是最头像数是4个,二是头像数是2个时的布局是横着排的.其实当时GitHub上就有类似的开源控件,只是那个控件在每一次绘制View的时候都会新创建一些Bitmap对象,这肯定是不可取的,而且那个控件头像输入的是Bitmap对象,不满足需求.所以只能自己实现一个了.实现的时候也没有过多的考虑,传入头像Drawable对象,根据数量排列

  • Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

  • Android自定义View实现简单的圆形Progress效果

    先给大家展示下效果图,如果感觉不错,请参考实现思路: 我们要实现一个自定义的再一个圆形中绘制一个弧形的自定义View,思路是这样的: 先要创建一个类ProgressView,继承自View类,然后重写其中的两个构造方法,一个是一个参数的,一个是两个参数的,因为我们要在xml文件中使用该自定义控件,所以必须要定义这个两个参数的构造函数.创建完了这个类后,我们先不去管它,先考虑我们实现的这个自定义View,我们想让它的哪些部分可以由使用者自己指定,比如说这个Demo中我们让他的外面圆的外边框颜色和宽

  • Android 自定义View之边缘凹凸的优惠券效果的开发过程

    本篇文章讲的是自定义View之边缘凹凸的优惠券效果,之前有见过很多优惠券的效果都是使用了边缘凹凸的样式.和往常一样,主要总结一下在自定义View的开发过程中需要注意的一些地方. 按照惯例,我们先来看看效果图 一.写代码之前,我们先弄清楚view的启动过程: 之所以想要弄清楚这个问题是因为代码里面用到了onSizeChanged()方法,一开始我有点犹豫onSizeChanged是在什么时候启动的呢,所以看看View的启动流程吧 package per.lijuan.coupondisplayvi

  • Android 自定义View实现任意布局的RadioGroup效果

    前言 RadioGroup是继承LinearLayout,只支持横向或者竖向两种布局.所以在某些情况,比如多行多列布局,RadioGroup就并不适用 . 本篇文章通过继承RelativeLayout实现自定义RadioGroup,实现RadioButton的任意布局.效果图如下: 代码(RelativeRadioGroup) /** * Author : BlackHao * Time : 2018/10/26 10:46 * Description : 自定义 RadioGroup */ p

  • Android自定义View实现抖音飘动红心效果

    本文实例为大家分享了Android自定义View实现抖音飘动红心效果的具体代码,供大家参考,具体内容如下 自定义View--抖音飘动红心 效果展示 动画效果 使用自定义view完成红心飘动效果 View实现 动画:属性动画(位移+缩放+透明度+旋转) + 随机数:(属性动画参数+颜色选取) View /** * 飘心效果 * 1.创建ImageView * 2.ImageView执行组合动画 * 3.动画执行完成后销毁View */ public class FlyHeartView exten

  • Android自定义View实现APP启动页倒计时效果

    Android自定义View实现APP启动页倒计时效果,供大家参考,具体内容如下 之前也是做过APP启动页的倒计时效果,但是只有文字变化,没有动画效果,这次通过使用自定义View控件来制作一个带有动画效果的倒计时. 倒计时效果的基本思路如下: Canvas提供了绘制弧形的方法,drawArc(),使用这个方法通过定时刷新计算当前弧形的角度,就可以模拟出倒计时的动画效果,同时借助drawText()方法可以实现倒计时文字.(1)继承View(2)使用canvas的drawArc()来绘制弧形,模拟

  • Android自定义View实现圆环带数字百分比进度条

    分享一个自己制作的Android自定义View.是一个圆环形状的反映真实进度的进度条,百分比的进度文字跟随已完成进度的圆弧转动.以下是效果图: 这个自定义View可以根据需要设定圆环的宽度和百分比文字的大小. 先说一下思路:这个View一共分为三部分:第一部分也就是灰色的圆环部分,代表未完成的进度:第二部分是蓝色的圆弧部分,代表已经完成的进度:第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度. 下面是View的编写思路: ①:定义三个画笔,分别画灰色圆环,蓝色圆弧,红色文字: ②:

随机推荐