自定义的Drawable draw()方法没有被调用(Android)

3

对于我的项目,我需要从网络上下载图片,因此我已经实现了一个简单的类:

@SuppressWarnings("deprecation")
public class DynamicDrawable extends BitmapDrawable{
    private  Drawable drawable;

    @Override
    public void draw(Canvas canvas) {
        // override the draw to facilitate refresh function later
        if(drawable != null) {
            drawable.draw(canvas);
        }
        Log.d("dnull", String.valueOf(drawable == null));
    }
    protected void setDrawable(Drawable drawable){
        this.drawable = drawable;
    }
}

有一个处理程序用于获取和解析图像,将其异步添加到类中并使视图无效,我已经检查过并且正常工作。 drawable变量不为空。 然后将其添加到ImageView中。但是,draw()方法从未被调用。即使它第一次被添加时也是如此。以下是图像进入视图的代码:

@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;

if(view == null){
    view = inflater.inflate(R.layout.view_concerteposter, parent,false);
}

ConcertPoster poster = posters.get(position);

ImageView iconView = (ImageView)view.findViewById(R.id.ticketBuy_icon);
TextView titleView = (TextView)view.findViewById(R.id.ticketBuy_name);
TextView dateView = (TextView)view.findViewById(R.id.ticketBuy_date);

iconView.setImageDrawable(poster.getImage());
System.out.println(poster.getImage());
titleView.setText(poster.getTitle());
dateView.setText(poster.getDate());

return view;
}

是的,我已经检查了这些对象,它们都是正确的,并且它们内部包含了正确的可绘制图形。

如果有需要帮助的地方,请告知。


看起来你期望在调用setImageDrawable()时自动调用draw()方法,但是为什么你会有这个期望呢?文档并没有指定这是预期的行为。 - mttdbrd
这种情况通常发生在普通的可绘制对象中。此外,它无法手动调用,因为Canvas对象由系统持有且不可获取。 - Alex
文档中说:“手动将此视图(及其所有子项)呈现到给定的画布中。”据我所知,您应该在提供的画布上绘制。不过我会测试一下并告诉您我的发现。 - mttdbrd
实际上,覆盖protected void onDraw(Canvas c)似乎是正确的方法,因为该方法将在invalidate时调用。正如文档所说,“实现此功能以进行绘图。” - mttdbrd
3个回答

0
在convertView的onDraw()方法中,您应该手动调用Drawable的draw()方法。
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}

请点击这里获取更多信息。


0

Canvas does not draw in Custom View的帖子中描述的解决方案解决了我的问题。

您的onDraw方法从未被调用,您需要在Custom View的构造函数中调用setWillNotDraw(false)以使onDraw实际被调用


0

重写getIntrinsicHeight()/getIntrinsicWidth()并返回非零值将解决问题。

请参见ImageView#setImageDrawable(Drawable)

public void setImageDrawable(@Nullable Drawable drawable) {
        if (mDrawable != drawable) {
           //...

            updateDrawable(drawable);

            if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
                requestLayout();
            }
            invalidate();
        }
    }

然后查看ImageView#updateDrawable(Drawable):
private void updateDrawable(Drawable d) {
        //...
        if (d != null) {
            //...
            mDrawableWidth = d.getIntrinsicWidth();
            mDrawableHeight = d.getIntrinsicHeight();
            //...

            configureBounds();
        } else {
            mDrawableWidth = mDrawableHeight = -1;
        }
    }

这里使用 mDrawableWidthmDrawableHeight 分别设置了 d.getIntrinsicWidth()d.getIntrinsicHeight()

请参见 ImageView#onDraw(Canvas):

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mDrawable == null) {
            return; // couldn't resolve the URI
        }

        if (mDrawableWidth == 0 || mDrawableHeight == 0) {
            return;     // nothing to draw (empty bounds)
        }
    //...
    }

如果 mDrawableWidth == 0 或者 mDrawableHeight == 0,ImageView 将不会调用 Drawable.draw(Canvas)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接