Rendering Inside onDraw(Canvas)

When your application is launched, all of its views are invalid. This means that they have not drawn anything to the screen. To fix this situation, Android calls the top-level View’s draw() method. This causes that view to draw itself, which causes its children to draw themselves. Those children’s children then draw themselves, and so on down the hierarchy. When all the views in the hierarchy have drawn themselves, the top-level View is no longer invalid.

To hook into this drawing, you override the following View method:

    protected void onDraw(Canvas canvas)

The call to invalidate() that you make in response to ACTION_MOVE in onTouchEvent(MotionEvent) makes the BoxDrawingView invalid again. This causes it to redraw itself and will cause onDraw(Canvas) to be called again.

Now let’s consider the Canvas parameter. Canvas and Paint are the two main drawing classes in Android:

  • The Canvas class has all the drawing operations you perform. The methods you call on Canvas determine where and what you draw – a line, a circle, a word, or a rectangle.

  • The Paint class determines how these operations are done. The methods you call on Paint specify characteristics – whether shapes are filled, which font text is drawn in, and what color lines are.

In BoxDrawingView.java, create two Paint objects in BoxDrawingView’s XML constructor.

Listing 31.8  Creating your paint (BoxDrawingView.java)

public class BoxDrawingView extends View {
    private static final String TAG = "BoxDrawingView";

    private Box mCurrentBox;
    private List<Box> mBoxen = new ArrayList<>();
    private Paint mBoxPaint;
    private Paint mBackgroundPaint;
    ...
    // Used when inflating the view from XML
    public BoxDrawingView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // Paint the boxes a nice semitransparent red (ARGB)
        mBoxPaint = new Paint();
        mBoxPaint.setColor(0x22ff0000);

        // Paint the background off-white
        mBackgroundPaint = new Paint();
        mBackgroundPaint.setColor(0xfff8efe0);
    }
}

Armed with paint, you can now draw your boxes to the screen.

Listing 31.9  Overriding onDraw(Canvas) (BoxDrawingView.java)

public BoxDrawingView(Context context, AttributeSet attrs) {
    ...
}

@Override
protected void onDraw(Canvas canvas) {
    // Fill the background
    canvas.drawPaint(mBackgroundPaint);

    for (Box box : mBoxen) {
        float left = Math.min(box.getOrigin().x, box.getCurrent().x);
        float right = Math.max(box.getOrigin().x, box.getCurrent().x);
        float top = Math.min(box.getOrigin().y, box.getCurrent().y);
        float bottom = Math.max(box.getOrigin().y, box.getCurrent().y);

        canvas.drawRect(left, top, right, bottom, mBoxPaint);
    }
}

The first part of this code is straightforward: Using your off-white background paint, you fill the canvas with a backdrop for your boxes.

Then, for each box in your list of boxes, you determine what the left, right, top, and bottom of the box should be by looking at the two points for the box. The left and top values will be the minimum values, and the bottom and right will be the maximum values.

After calculating these values, you call Canvas.drawRect(…) to draw a red rectangle onto the screen.

Run DragAndDraw and draw some red rectangles (Figure 31.5).

Figure 31.5  An expression of programmerly emotion

An expression of programmerly emotion

And that is it. You have now created a view that captures its own touch events and performs its own drawing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.87.133.69