yahya
yahya

Reputation: 4860

onDraw doesn't get called on custom view?

I'm trying to draw a rounded rect with a specific color, but i'm getting nothing. I've already done lots of googling, and found some questions like this and read them all. However, none of them solved my problem. Why my onDraw method is never called?

Any help is appreciated.

public class RoundedTagItem extends RelativeLayout {

    Context ctx;
    String colorString;
    int color;

    public RoundedTagItem(Context context) {
        super(context);
        this.ctx = context;
        color = Color.WHITE;
        this.setWillNotDraw(false);
        this.setPadding(10, 0, 10, 0);
    }

    public RoundedTagItem(Context context, String color) {
        super(context);
        this.ctx = context;
        this.colorString = color;
        this.setWillNotDraw(false);
        this.setPadding(10, 0, 10, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {

       if(colorString != null)
             color = Color.parseColor("#" + colorString);

       int rectValue = 35;
       Log.d("Rounded", "rectValue: " + rectValue);
       RectF rect1 = new RectF(0, 0, rectValue, rectValue);

       Paint paint = new Paint();
       paint.setStrokeWidth(1);
       paint.setStrokeCap(Paint.Cap.ROUND);
       paint.setStyle(Paint.Style.FILL);
       paint.setAntiAlias(true);
       paint.setColor(color);

       canvas.save();
       canvas.drawRoundRect(rect1, 10, 10, paint);
       canvas.restore();

       super.onDraw(canvas);
    }

    public void ChangeBackgroundColor(String colorString) {
        color = Color.parseColor(colorString);
        invalidate();
    }

}

And then I put icons on this custom view on my main class:

// add category items to view
LinearLayout categories = (LinearLayout) findViewById(R.id.detailTagImagesLayout);
for(int i = 0; i < item.getCategoryItems().size(); i++) {

    RoundedTagItem v = null;
    if(i == 0) 
        v = new RoundedTagItem(DetailActivity.this, 
                           item.getCategoryItems().get(i).getColorCode());
    else 
        v = new RoundedTagItem(DetailActivity.this);            

    ImageView img = new ImageView(DetailActivity.this);
    img.setImageDrawable(Drawable.createFromPath(
                     item.getCategoryItems().get(i).getLightIconUrl()));
    v.addView(img);

    v.setTag(i);
    v.setOnClickListener(new TagClickListener());               

    categories.addView(v);
}

Upvotes: 2

Views: 2685

Answers (2)

Tamir Scherzer
Tamir Scherzer

Reputation: 1035

Try to create a simple single RelativeLayout XML (rounded_tag_item.xml), and inflate the custom view:

public class RoundedTagItem extends RelativeLayout {

    public RoundedTagItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public RoundedTagItem(Context context) {
        super(context);
        init(context);  
    }

    private void init(Context context) {
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (inflater != null) {       
            RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.rounded_tag_item, new RelativeLayout(context));

            // rest of stuff...
        }
    }
}

Upvotes: 0

Tiago Almeida
Tiago Almeida

Reputation: 14237

Some improvements/problems you can make/fix...

You can move these lines to your constructor:

if(colorString != null)
   color = Color.parseColor("#" + colorString);

Since this colorString never changes and the way you are doing it now you are calculating it every time onDraw is called (and he will be called a lot of times).

Second please move your super.onDraw(canvas) to your first line.

Third you need to define your LayoutParams on your constructor. If a View has 0 width/height its draw will never be called!

this.setLayoutParams(new LayoutParams(150, 150));

At last please make sure you are using your RoundTagItem. You can add this view to your xml using a tag like this: <your.package.RoundTagItem> where your.package is the package that you are using (com.something.blabla). If you use it like this please be sure you define the layout_width and the layout_height.

You can also add your view programmatcly by adding to your root view (you get it by using findViewById(R.layout.your_root)) or by setting your view as the main content.

RoundedTagItem myView = new RoundedTagItem(this);
setContentView(myView);

Upvotes: 1

Related Questions