在Android的ImageView中快速绘制位图

时间:2014-03-27 18:09:08

标签: android android-canvas android-imageview draw picasso

我有一个从ImageView扩展的类(实际上是三个类,它们从另一个扩展,但这并不相关),可以在ImageView绘制的drawable周围执行一些自定义绘制。现在,我的代码很好(或者至少我认为很好,在分析它之后只需要运行一些ms)但是当设置图像(图像加载为Bitmap)时,所有内容都会挂起大约500毫秒,而不是很多,但足以引人注目。

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

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

注意:相对于ImageView,图像缩小到一个稍低的尺寸,因此已经尝试过此解决方案。

现在问题:如何以高效,快速的方式显示此位图?

提前谢谢大家!

drawing profile

编辑:[{3}}

提出的一些代码的时间
@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()是一个私有方法,在子类中它们之间没有关系,我已经检查了它被调用了多少次,并且我的测试似乎在第一次创建/活动时只调用了两次娱乐。

任何想法?

0 个答案:

没有答案