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

解决RecyclerView Item自定义View onDraw卡顿的方法

程序员文章站 2022-05-30 22:49:28
...

        最近实现了一个功能,是在列表Item中绘制自定义控件,刚开始就觉得单单做这个功能非常简单,但是最后优化好的时候觉得绕了一大圈,因此记录一下。

 

        Item的内容大致如下,还有一些别的数据,这个图不是实现内容。

解决RecyclerView Item自定义View onDraw卡顿的方法

 

刚开始是用一个for循环去drawPath去绘制一段段折线图和下面的着色区域,好了,这样是可以实现了,但是上下滑动复用view冲洗你绘制的时候非常的卡顿,原先是一直在for循环drawPath更新主线程。

这里其实优化比较方便,只需要在for循环里path.moveTo和path.lineTo处理好一段path,最后只进行一次drawPath就完成了!这里其实已经完成了我要的需求。但是如果有些内容必须要通过循环一次次地绘制呢?那不是会非常地卡?

 

对于这种有可能会出现的需求,我必须要提前做好应对方案。我的思路就是第一次真实地去循环绘制,把它保存成图片的形式,接着在上下滑动复用view的时候直接绘制这张保存的图片。

 

大致代码如下:

protected void onDraw(Canvas canvas){
    if(mBitmap == null){
        Bitmap mBitmap = Bitmap.createBitmap(getWidth(), getHeight(),Bitmap.Config.ARGB_8888); 
        Canvas bitmapCanvas = new Canvas(mBitmap);

        for(int i=0;i<=50;i++){
            bitmapCanvas.drawPath(.....);
        }

        canvas.drawBitmap(mBitmap,0,0,null);
}else{
    canvas.drawBitmap(mBitmap,0,0,null);
}

        这里有bug,而且还需要优化,一个View第一次只保存它所属的Bitmap(比如第0个Item),但是在滑动复用的时候这个View真实要展示的是其他数据的Bitmap,比如第9个Item复用了这个View,我们只需要重新bind这个data到view里就好,那么最好的方式就是自己创建一个Bitmap的HashMap去管理每种data对应的bitmap,代码就不贴了。

        但是这样又有一个问题,上下滑动复用的时候onBindViewHolder会自然调用第一次想要个更新自定义View更新数据的那个方法。例如mView.updateData(data)。这里我通过一些记录来进行区别。

if (!set.contains(xxx)) {
    mView.forceDrawData();
    set.add(xxx);
} else {
    mView.justDrawBitmap();
}