Search code examples
imageviewandroid-drawableandroid-glideondraw

Can an ImageView be set up so that onDraw is only called in certain cases?


My app needs to show a set of images. Some images are built-in, while others have been added by the User. I've created a class for this, called SymbolBox (I've simplified it here):

public class SymbolBox extends android.support.v7.widget.AppCompatImageView {

 private FullSymbol  mSymbol; // Symbol to show                 
 private final Paint mPaint;  // Paint variable to use

 // Constructor initialises options and sets up the paint object
 public SymbolBox(Context context, AttributeSet attrs) {
        super(context, attrs);

        mPaint          = new Paint();

 }

 // Set the symbol
 public void setSymbol(FullSymbol symbol) { 
    this.mSymbol = symbol; 
 }

 // Draw the symbol
 protected void onDraw(Canvas canvas) {

   if(this.mSymbol == null) return;
   String drawableUrl  = mSymbol.getUrl();
   if(drawableUrl != null) return;  // Only use this to draw from base

   // Get canvas size
   float height = getHeight();
   float width  = getWidth();

   // Draw the symbol
   String drawableName = mSymbol.getBase();
   Context context = getContext();


     if((drawableName == null) || (drawableName.equals(""))) { drawableName = "blank"; }

     Resources resources = context.getResources();
     final int resourceId = resources.getIdentifier(drawableName,
                    "drawable",
                    context.getPackageName());

     Drawable d;
     if (resourceId != 0) {
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
         d = resources.getDrawable(resourceId, context.getTheme());
       } else {
         d = resources.getDrawable(resourceId);
       }
       d.setBounds(0, 0, getWidth(), getHeight());
       d.draw(canvas);
     }
}

FullSymbol is defined like this:

public class FullSymbol {

    private String  name, base;
    private String  url;

    // CONSTRUCTOR
    public FullSymbol() {}

    public String getBase() { return this.base; }
    public String getName() { return name; }
    public String getUrl() { return url; }

    public void setBase(String newBase) { this.base = newBase; }
    public void setName(String newName) { this.name = newName; }
    public void setUrl(String newUrl)   { this.url = newUrl; }
}

Each FullSymbol can have either a base or a url (if it has neither, the base will be set to "blank"). The base is a reference to a built-in image; url is a reference to an online image (which has been uploaded by the user).

In the Fragment which calls all of this, I'm setting up a SymbolBox in the layout, and then using Glide to load the image into the SymbolBox (I'm having issues downloading the uploaded image, so just using a fixed url for now):

SymbolBox test = rootView.findViewById(R.id.testSymbol);
Glide.with(this).load("http://path/to/image").into(test);

So, if the FullSymbol has a url, then the image at that url should be loaded into the SymbolBox using Glide. If it has no url, then the value of base should be used and the image is drawn using drawables.

The problem I'm having is that the Glide part only shows anything if onDraw is taken out of the SymbolBox class (ie commented out completely; if I just have an empty function it doesn't work). But I need the onDraw to draw the image if there's no url and I'm using the base.

Is there a way to somehow ignore onDraw if the url exists, but include it otherwise? Or a different way to draw from the base - I can create a function, but I need to access the Canvas. How do I resolve this?


Solution

  • I managed to resolve this - I added a call to the super method of onDraw in SymbolBox:

    protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
       ... rest of the code stayed the same ...
    
    }
    

    and it worked.