简体   繁体   中英

Custom Drawable draw() method not being called (Android)

For my project I am downloading images from the web, so I have implemented a simple class for it:

@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;
    }
}

There is a handler that gets and parses the image, adds it asynchronously to the class and invalidates the view, which I have checked and works fine. The drawable variable is not null. It is then added to an ImageView. However, the draw() method is never called. Not even when it is first added. Here is the code where the image enters the view:

@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;
}

Yes, I have checked the objects, they are all correct and have the correct drawables in them.

Any help would be appreciated.

In the onDraw() method for convertView you should manually call the draw() method for the Drawable.

protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}

See here for more information.

The solution described on post Canvas does not draw in Custom View solved my case.

Your onDraw method is never called, you need to call setWillNotDraw(false) on the constructor of your Custom View in order to get onDraw actually called

Override getIntrinsicHeight() / getIntrinsicWidth() and return nonzero value will solve the problem.

See ImageView#setImageDrawable(Drawable) :

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

            updateDrawable(drawable);

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

Then see ImageView#updateDrawable(Drawable) :

private void updateDrawable(Drawable d) {
        //...
        if (d != null) {
            //...
            mDrawableWidth = d.getIntrinsicWidth();
            mDrawableHeight = d.getIntrinsicHeight();
            //...

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

Here mDrawableWidth and mDrawableHeight has been set with d.getIntrinsicWidth() and d.getIntrinsicHeight() ;

The see 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)
        }
    //...
    }

You can see if mDrawableWidth == 0 or mDrawableHeight == 0 , ImageView will not invoke Drawable.draw(Canvas) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM