使用TextView实现类似于QQ钱包里面的余额数字的快速增加或减少效果

使用TextView实现类似于QQ钱包里面的余额数字的快速增加或减少效果

在完成一个需求时,存在一个在一定的时间内让数字从一个值变化到另一个值的需求,当时一想有两种方式完成: 1、 使用timer在,给定的时间里面让数值加单位数值(1或者0.1等),并去改变view的text 2、 使用valueAnimator.ofFolat将初始值和终点值都放到里面,在动画改变的回调里面去是设置view的text 两种方式都可以实现,但是各有优缺点: 第一种方法:、 优点:可以实现每一单位数值的累加(比如:从1到100,每次加1.那么没次得到值就是1、2、3…100) 缺点:每一次增加的操作的时间都是一定的,导致数值过大会花很长的时间才能完成数值变化的过程。 第二种方法: 优点:通过设置动画的完成时间,可以保证数值变化的时间一定的。 缺点:理论上不能实现每一次设置给textview的值都是变化了单位数值,但是视觉上不影响。 本文采用了第二种方式实现,同时还考虑了到连续的设置不同的数值(当第一调用是从0到100的变化,在第一次变化还没有做完时,又发生了第二次调用设置值(100到200)的情况),具体实现代码如下(kotlin):

/**

  • Created by Alan on 2018/4/14. */ class NumberFastAddFactory { private val TAG = "NumberFastAddFactory"

    fun addNumber(textView: TextView, endNumber: Float, isDoAlphaAnim: Boolean) {

     if (isHasThisTextView(textView)) {
         textView.setTag(R.id.end_number, endNumber)
         startAddAnim(true, textView, isDoAlphaAnim)
     } else {
         textViewList.add(textView)
         textView.setTag(R.id.current_number, getCurrentNumber(textView))
         textView.setTag(R.id.end_number, endNumber)
         startAddAnim(false, textView, isDoAlphaAnim)
     }
    

    }

    private fun startAlphaAnim(textView: TextView) { var animSet = AnimatorSet() var disPlayAlphaAnim = ObjectAnimator.ofFloat(textView, "alpha", 0F, 1F) disPlayAlphaAnim.duration = ALPHA_ANIM_TIME var hideAlphaAnim = ObjectAnimator.ofFloat(textView, "alpha", 1F, 0F) hideAlphaAnim.duration = ALPHA_ANIM_TIME hideAlphaAnim.startDelay = ALPHA_ANIM_TIME animSet.play(disPlayAlphaAnim).before(hideAlphaAnim) animSet.start() }

    private fun getCurrentNumber(textView: TextView): Float { //如果为第一次做动画从0开始加 if (textView.getTag(R.id.current_number) == null) { return DEFAULT_NUMBER_TIME } return textView.getTag(R.id.current_number) as Float }

    private fun startAddAnim(isDoingAnim: Boolean, textView: TextView, isDoAlphaAnim: Boolean) { if (isDoingAnim) { (textView.getTag(R.id.current_anim) as ValueAnimator)?.cancel() } Log.d(TAG, "当前值是:${textView.getTag(R.id.current_number)}结尾值:${textView.getTag(R.id.end_number)}")

     var addAnim = ValueAnimator.ofFloat(textView.getTag(R.id.current_number) as Float, textView.getTag(R.id.end_number) as Float)
     addAnim.duration = ADD_NUMBER_TIME
     addAnim.addUpdateListener { animation ->
         textView.text = DecimalFormat("###,###,###.##").format(animation?.animatedValue)
         textView.setTag(R.id.current_number, animation?.animatedValue)
         Log.d(TAG, "当前的设置值是:${DecimalFormat("###,###,###.##").format(animation?.animatedValue)}")
    
     }
     addAnim.addListener(object : Animator.AnimatorListener {
         override fun onAnimationEnd(animation: Animator?) {
             textView.setTag(R.id.current_anim, null)
             textViewList.remove(textView)
         }
    
         override fun onAnimationRepeat(animation: Animator?) {
         }
    
         override fun onAnimationCancel(animation: Animator?) {
         }
    
         override fun onAnimationStart(animation: Animator?) {
             if (isDoAlphaAnim) {
                 startAlphaAnim(textView)
             }
         }
     })
     textView.setTag(R.id.current_anim, addAnim)
     addAnim.start()
    

    }

    private fun isHasThisTextView(textView: TextView): Boolean { return textViewList.contains(textView) }

    companion object { var instance = NumberFastAddFactory() var textViewList = ArrayList<TextView>() val ADD_NUMBER_TIME = 150L val ALPHA_ANIM_TIME = 50L val DEFAULT_NUMBER_TIME: Float = 0F } } 有些人可能会有疑问R.id.end_number…这些是什么,这个是在给view setTag()的时候的id,由于不能在类里面定义变量,只能在res\values路径下创建ids.xm文件定义。

<?xml version="1.0" encoding="utf-8"?>

<resources> <!--NumberFastAddFactory中做动画所用id--> <item name="lg_value_text_value" type="id"></item> <item name="current_number" type="id"></item> <item name="start_number" type="id"></item> <item name="end_number" type="id"></item> <item name="current_anim" type="id"></item> </resources>

转载于:https://my.oschina.net/u/2453842/blog/1796558

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值