matt5784
matt5784

Reputation: 3085

Problems drawing text onto an ImageView using a Canvas

I'm trying to implement a footer for my ListView which will act as a menu-type frame with five elements. I want the elements to be able to (dynamically, based on user input) display either images or text (or possibly both, but I'm not there yet). Eventually it will be more interactive but for now I was trying to implement it so that the ImageView (which by default displays an image) would erase the image and display text instead.

I thought the best way to implement this was to draw text on a canvas and use the android.view.View.draw(canvas c) method to draw it onto the ImageView. However, I'm having trouble doing this. Specifically, I can modify the view in almost any way (set the background color, change the drawable, etc etc) and it all works fine, and the code to draw the canvas compiles properly, but it doesn't do anything at runtime. The view remains completely unchanged.
(Note: I've tried to eliminate any stupid mistakes through code (i.e. made sure text wasn't transparent/same color as bg, made sure text was drawn inside the area of the view, etc) but I am not 100% it's error free.)

I tried both drawing to the view passed into the onClick function and drawing to a new ImageView constructed from the passed view - neither works. Does anyone have any suggestions? Code follows:

login_button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            Bitmap img = Bitmap.createBitmap( 60, 60, Config.ARGB_8888);
            Canvas c = new Canvas();
            c.setBitmap(img);

            Paint myPaint = new Paint();
            myPaint.setTypeface(mFace);
            myPaint.setColor(android.R.color.black);
            myPaint.setTextSize(2);
            myPaint.setTextAlign(Paint.Align.LEFT);

            String content = "testing";
            c.drawText(content, 0,0, myPaint);
            view.draw(c);//does nothing
            ImageView view2 = (ImageView) view;
            view2.setBackgroundColor(android.R.color.white); //this works perfectly
            view2.draw(c);//does nothing
            Toast.makeText(MainListView.this, ""+c.getHeight(), Toast.LENGTH_SHORT).show(); //making sure c has height - this returns 60 as expected
            Toast.makeText(MainListView.this, "end of method", Toast.LENGTH_SHORT).show();
        }
    });

Upvotes: 1

Views: 1452

Answers (2)

ab11
ab11

Reputation: 20090

You could create the Canvas from the Bitmap, and set the Bitmap as the Image for your ImageView.

Bitmap img = Bitmap.createBitmap( 60, 60, Config.ARGB_8888);
Canvas c = new Canvas(img);

Paint myPaint = new Paint();
myPaint.setTypeface(mFace);
myPaint.setColor(android.R.color.black);
myPaint.setTextSize(2);
myPaint.setTextAlign(Paint.Align.LEFT);

String content = "testing";
c.drawText(content, 0,0, myPaint);
ImageView view2 = (ImageView) view;
view2.setImageBitmap(img);
Toast.makeText(MainListView.this, ""+c.getHeight(), Toast.LENGTH_SHORT).show(); //making sure c has height - this returns 60 as expected
Toast.makeText(MainListView.this, "end of method", Toast.LENGTH_SHORT).show();

Although, I believe the "right" way to do this is to use an extension of View and override the onDraw method to draw differently based on some local variables:

login_button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            ((MyView)view).mContextVariable = true; //or false, etc
            //you might not need this invalidate, because the click event probably causes and invalidate to be called
            view.invalidate();
        }
    }

    class MyView extends View
    {
        Paint myPaint;
        boolean mContextVariable;

        public MyView(Context context) 
        {
            super(context);

             myPaint = new Paint();
             myPaint.setTypeface(mFace);
             myPaint.setColor(android.R.color.black);
             myPaint.setTextSize(2);
             myPaint.setTextAlign(Paint.Align.LEFT);
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            if(mContextVariable)
            {
                //draw something
            }
            else
            {
                //draw something else
            }
            canvas.drawText("testing", 0,0, myPaint);
        }
    }

Upvotes: 0

Darshan Rivka Whittle
Darshan Rivka Whittle

Reputation: 34031

View.draw(Canvas) draws the View onto the Canvas, not vice versa like you seem to expect.

If you want to do it along the lines that you already are, you need to extend an existing View class, likely TextView or ImageView, and override onDraw(), as explained in the Custom Components Dev Guide.

I think what I would do is use something like a FrameLayout and set it to contain either the appropriate TextView or ImageView as necessary. That seems cleaner than manually rendering text in an ImageView.

Upvotes: 1

Related Questions