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

android custom drawable
android draw drawable on canvas
android custom drawable xml
android create drawable programmatically
android draw custom shape canvas
android:drawable
android drawing with canvas code
draw image on canvas android example

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.

Custom Drawing, The setBounds(Rect) method must be called to tell the Drawable where it is Custom drawables classes may be used in XML in multiple ways: as getBounds(), but the returned object is guaranteed to not be changed later by the The bounds specify where this will draw when its draw() method is called. Why isn't the paintComponent method being called? `paint` method isn't called after `QGraphicsView` scroll; Swift: didSelectContactProperty Isn't Called; Why isn't AngularJS form handler method being called? Custom Drawable draw() method not being called (Android) Why isn't drawRect: getting called? Why isn't __instancecheck__ being called


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

Drawable, Animatable � Animatable2 � Drawable. You should not call methods that perform these actions on views yourself unless you are Drawing, onDraw( android.graphics. Attaching, onAttachedToWindow(), Called when the view is attached to a window. in a ViewGroup, and with setZ(float) custom Z values} set on Views. The most important step in drawing a custom view is to override the onDraw() method. The parameter to onDraw() is a Canvas object that the view can use to draw itself. The Canvas class defines methods for drawing text, lines, bitmaps, and many other graphics primitives.


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).

View, Here is a complete implementation of a custom ViewGroup that implements a @Override public boolean shouldDelayChildPressedState() { return false; } the ViewGroup should always draw its children using their drawing cache or not. Called when a child view has changed whether or not it is tracking transient state. On Android 7.0 (API level 24) and higher, you can also define instances of your custom drawable with XML in the following ways: Using the fully-qualified class name as the XML element name. For this approach, the custom drawable class must be a public top-level class:


ViewGroup, Exercise: Create Custom rounded corner drawable If you do not provide bitmaps for all supported resolutions, the Android system scales the closest fit up or down. Android allows you to use the Bitmap class for working with bitmaps. and assign it to a View via the setBackgroundResource() method. <! Unlike iOS, Android does not provide such view, so I had to implement it as a custom one. I spent a decent amount of time trying to implement it. Fortunately enough that view is quite reusable in projects nowadays , so to save personal time and the time of other developers, I decided to make a public library based on that view.


Canvas and Drawables, Drawing in Android; What is a Canvas object? Using a drawable is your best choice when you want to draw simple graphics that do not need You can do your own custom 2D drawing using the drawing methods of the Canvas class. The onSizeChanged() method is called when your View is first assigned a size, and� Jan 5, 2016 • David Medenjak. There are many opportunities where the usage of a custom drawable will lead to nice, clean, and reusable results. If you need to display changing text inside an icon or introduce a custom progress indicator like in Modifying the resource image of Progress Bar on Stack Overflow, you can easily do so with custom drawables.


Android Drawables - Tutorial, Keep in mind that Android drawables require a bit of housekeeping which we covered There is no point in images staying in memory when Android is no longer displaying the view - it may have scrolled off-screen, or otherwise not be drawing. mDraweeHolder; @Override public void onDetachedFromWindow() { super. The Android framework will call the onDraw () method to ask our View to draw itself. The onDraw () method will be called by the Android framework on a need basis; for example, whenever our application wants to draw itself, this method will be called. We have to call the invalidate () method whenever we want our view to redraw itself.