我有一个从 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()
是一个私有方法,在子类中它们之间没有关系,我检查了它被调用了多少次,对于我的测试,似乎在第一次创建/活动重新创建时只被调用了两次。
任何想法?