Views Example

This example shows how to create a custom view that can be decorated using paints and a canvas.

A screenshot of the application.

Another example that shows similar techniques is the Bitmap example.

We import the classes and modules that will be needed by the application. The most relevant are the classes from the android.view module.

import android.app
import android.content
import android.graphics
import android.os
import android.view

The ViewActivity is derived from the standard Activity class and represents the application. Android will create an instance of this class when the user runs it, and the activity will present a graphical interface to the user.

class ViewActivity(android.app.Activity):

    def __init__(self):
    
        android.app.Activity.__init__(self)

The initialisation method simply calls the corresponding method in the base class. This must be done even if no other code is included in the method.

The onCreate method is called when the activity is created by Android. The return type and parameter types expected by the method are declared using the following decorator. As with the __init__ method, we must call the corresponding method in the base class.

    @args(void, [android.os.Bundle])
    def onCreate(self, bundle):
    
        android.app.Activity.onCreate(self, bundle)
        
        view = DrawView(self)
        self.setContentView(view)

The user interface is an instance of the custom DrawView that we define below. As with standard views, we pass the activity instance as an argument to the class when we create it. We set the view as the main view in the activity.

The DrawView class is derived from the standard View class and is used to display custom graphics in the activity.

As with other views, the initialisation method accepts a Context as its parameter and initialises itself by calling the initialisation method of the View class.

class DrawView(android.view.View):

    @args(void, [android.content.Context])
    def __init__(self, context):
    
        android.view.View.__init__(self, context)
        
        self.paint = android.graphics.Paint()
        self.x = 0
        self.y = 0
        self.r = 10

We create a Paint object that will be used to draw decorations in the view, as well as three other attributes that define the position and size of a circle that we will display.

The onSizeChanged method is called when the view is first shown and whenever it changes size afterwards. The first time this method is called, the oldWidth parameter will be 0. We use this to define the initial position of the circle.

    @args(void, [int, int, int, int])
    def onSizeChanged(self, width, height, oldWidth, oldHeight):
    
        if oldWidth == 0:
            self.x = width/2
            self.y = height/2

The onDraw method is called when the view needs to be displayed. The parameter is a Canvas object that we draw onto. We call the onDraw method in the base class before adding our own decorations.

    @args(void, [android.graphics.Canvas])
    def onDraw(self, canvas):
    
        android.view.View.onDraw(self, canvas)

We first change the colour of the paint to a shade of green and use it to draw the view's background.

        self.paint.setARGB(255, 0, 255, 160)
        canvas.drawPaint(self.paint)

Then, we change the colour to a dark blue and use it to draw a circle with the position and radius defined earlier.

        self.paint.setARGB(255, 0, 0, 160)
        canvas.drawCircle(self.x, self.y, self.r, self.paint)

The onTouchEvent method is called when the view receives touch events. We respond to all touch events that are sent to the view.

    @args(bool, [android.view.MotionEvent])
    def onTouchEvent(self, event):
    
        self.x = event.getX()
        self.y = event.getY()
        self.invalidate()
        return True

For each event we receive, we update the coordinates stored as instance attributes before invalidating the view, causing the onDraw method to be called. Finally, we return True to indicate that we have handled the event.

Files