1

我有一个从 ImageView 扩展的类(实际上是三个从另一个扩展的类,但这不相关)围绕 ImageView 绘制的可绘制对象执行一些自定义绘图。现在,我的代码很好(或者至少我认为很好,在对其进行分析后,它只需要几毫秒即可运行)但是在设置图像(作为位图加载的图像)时,一切都会挂起大约 500 毫秒,而不是很多但足以引起注意。

可悲的是,这个类必须在 GridView(或 ListView)中使用,一切都很好,直到图像被加载(通过Picasso,所以显然我的问题不是在主线程上加载图像),图像是在图像视图中设置。现在,由于每个 ImageView 需要数百毫秒来显示图像,因此如果正在设置图像,它会使 GridView 在滚动时滞后。

现在你可以从下图(DDMS 提供的方法分析结果)中看到,需要这么多时间的是方法GLES20Canvas.nDrawDisplayList

注意:图像被缩小到相对于 ImageView 稍微低一点的尺寸,所以这个解决方案已经被尝试过了。

现在问题来了:我怎样才能以高效和快速的方式显示这个位图?

谢谢大家!

绘图轮廓

编辑:JakeWharton提出的一些代码的时间

@Override
public boolean onPreDraw() {
    if (mNeedRedraw)
        updateAttrs();
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.save();
    if (mClippingPath != null) {
        canvas.clipPath(mClippingPath);
    }
    super.onDraw(canvas);
    canvas.restore();
    if (mBorderPath != null && mBorderPaint != null) {
        canvas.drawPath(mBorderPath, mBorderPaint);
    }
}

现在其他三个子类有一个非常相似的代码,显然mNeedRedraw只有在真正需要时才设置标志,因为它重新计算正确绘图所需的所有东西(但总是重用对象,在updateAttrs()方法中不进行对象分配。

只是为了完整起见:

第一个子类的平局:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (mBackgroundPaint != null && mBackgroundPath != null) {
        canvas.drawPath(mBackgroundPath, mBackgroundPaint);
        canvas.drawTextOnPath(mText, mBackgroundPath, mHorizontalOffset, mMidTextHeight, mTextPaint);
        if (mIcon != null && mIconTransformationMatrix != null) {
            canvas.drawBitmap(mIcon, mIconTransformationMatrix, mTextPaint);
        }
    }
}

@Override
public boolean onPreDraw() {
    boolean result = super.onPreDraw();
    if (mFooNeedRedraw)
        updateAttrs();
    return result;
}

第二个子类的平局:

@Override
public boolean onPreDraw() {
    boolean result = super.onPreDraw();
    if (mBarNeedRedraw)
        updateAttrs();
    return result;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (mArc != null && !isInEditMode()) { 
        canvas.drawPath(mArc, mArcPaint);
    }
}

最后是最后一个子类的代码:

@Override
public boolean onPreDraw() {
    boolean result = super.onPreDraw();
    if (mBazNeedRedraw || mTrackNeedRedraw)
        updateAttrs();
    return result;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(mTrackVisible)
        canvas.drawBitmap(mThumbTrackIcon, mThumbIconTransformationMatrix, mThumbPaint);
}

这是所有的了。现在,这updateAttrs()是一个私有方法,在子类中它们之间没有关系,我检查了它被调用了多少次,对于我的测试,似乎在第一次创建/活动重新创建时只被调用了两次。

任何想法?

4

0 回答 0