记一次自定义View的优化

2021-02-04 10:44:44 浏览数 (1)

项目中用到一个自定义View,功能类似于跑马灯。但是在低端机上有明显的卡顿,故拿出部分代码做优化。代码如下

代码语言:javascript复制
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (!TextUtils.isEmpty(mText) && mValueAnimator?.isRunning == true && mStartY != -1) {
            val x = mWidth - (mWidth   mPaint.measureText(mText)) * mFraction
            val y = mStartY.toFloat()
            canvas.drawText(mText, x, y, mPaint)
        }
    }

通过查看 Android Profiler,可以知道

代码语言:javascript复制
onDraw      total = 6.7     self = 2.3     children = 4.4
                    6.1            1.7                4.3
                    6.4            2.0                4.3
                    6.6            2                  4.6

onDraw里面,很明显 self 里面的计算占了 2% 左右,其实可以优化. measureText 可以放到外面 canvas.drawText 占了4.5%左右,这一部分也可以优化

代码语言:javascript复制
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (mValueAnimator?.isRunning == true && mStartY != -1) {
            canvas.clipRect(0, mCLipTop, width, mCLipBottom)//限制在规定的区域内重绘
            val x = mWidth - (mWidth   mTxtWidth) * mFraction
            val y = mStartY.toFloat()
            canvas.drawText(mText, x, y, mPaint)
        }
    }

如上修改以后, self 降到 1% 左右,.同时 children 也降到 3% 左右(可见 canvas.drawText 还是很占CPU的) 从技术角度能做的优化其实已经差不多了,但是从需求的角度还是有优化的空间的 这个自定义View的功能就是跑马灯,就是让文字随着时间走.那么就可以想到两种解决方案 (1)画布移动 canvas.translate 这个方案的问题就是 translate 之后还是要 drawText, 还是很占CPU (2)整体移动 View, 也就是在 TextView 的基础上修改, 用 scrollTo 来处理

最终方案

代码语言:javascript复制
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (mValueAnimator?.isRunning == true) {
            val x = mWidth - (mWidth   mTxtWidth) * mFraction
            scrollTo(-x.toInt(), 0)
        }
    }

自定义View的优化最重要的就是一开始的时候选择相对好一点的实现方式,这样后期的优化工作可以少一些

0 人点赞