Presentation is loading. Please wait.

Presentation is loading. Please wait.

David Sutton 2D GRAPHICS IN ANDROID. INTRODUCTION AND OUTLINE  In this week’s session we will create a simple Kaleidoscope application. Topics that will.

Similar presentations


Presentation on theme: "David Sutton 2D GRAPHICS IN ANDROID. INTRODUCTION AND OUTLINE  In this week’s session we will create a simple Kaleidoscope application. Topics that will."— Presentation transcript:

1 David Sutton 2D GRAPHICS IN ANDROID

2 INTRODUCTION AND OUTLINE  In this week’s session we will create a simple Kaleidoscope application. Topics that will be covered include:  Obtaining a canvas  Drawing primitives  Clipping  Transformations  Drawable objects Do Exercise 1

3 HOW TO CREATE A VIEW ON WHICH TO DRAW GRAPHICS There are two ways to do this: 1.Extend the View class, or one of its subclasses. Then override the onDraw method. This method is preferrable when dealing with graphics that do not need to change rapidly. 2.Extend the SurfaceView class. If you do this you can arrange for graphics to be updated in a separate thread. This method is preferable for rapidly changing graphics. We shall not need rapid updates, so we will use method 1. Do Exercise 2

4 DRAWING AND THE CANVAS  To make our view draw any graphics we must override its onDraw method. This has the signature protected void onDraw(Canvas canvas)  A Canvas is a surface onto which we can draw things. The Canvas class contains methods which allow us to draw geometric shapes, images, coulour gradients, etc.

5 DRAWING AND PAINT OBJECTS The following code will draw a red circle on to a View public class KaleidoView extends View { private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setColor(Color.RED); canvas.drawCircle(100, 100, 50, paint); } The Paint class allows you to control the way that graphics are painted. For example the paint colour, whether shapes are filled or just outlined, whether anti- aliasing is used to smooth lines, and so on. Do Exercise 3

6 COLOUR IN ANDROID  In Android a colour is represented as an int value whose 4 bytes contain:  The red, green, blue values for the color  An “alpha” value, indicating the degree of transparency.  This is different from the way in which colour is represented in the standard Java API, which has a separate Color class.  Rather confusingly, Android also has a Color class. However this class is used to collect together a set of static methods and fields that are used to represent and manipulate int values that represent colours.

7 ADDING VIEWS TO AN ACTIVITY  If you have created your own View there are two ways of of making an activity display it. A.Add it to an XML layout file which is inflated by the activity. B.Add it programmatically within the Activity’s onCreate method. We don’t know how to do A yet, so we will do B. public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new KaleidoView(this)); } Do Exercise 4

8 PATHS AND SHAPES  The Canvas class contains methods for drawing images, colour gradients, and shapes.  We can draw more or less any shape by representing it as Path object.  A Path is a series of straight or curved lines.  Here is how we might represent a segment of a circle. 1. Draw an arc that sweeps out a part of the circle 2. Draw a line to the centre of the circle 3. Close the shape.

9 CREATING A PATH IN ANDROID boundingRect = new RectF(0,150,100,250); segment.addArc(boundingRect, 0, 30); segment.lineTo(50, 200); segment.close(); paint.setColor(Color.BLACK); canvas.drawPath(segment, paint); Do Exercise 5

10 CLIPPING  It is often useful to restrict the area of the canvas that can be updated by calls to methods that draw things. We do this by establishing a clip region.  The Canvas class contains methods that allow us to set up any shape as a clip region. These methods are quite similar to those that are used to draw shapes. Unclipped View Same View with a rectangular clip region Do Exercise 6

11 GEOMETRIC TRANSFORMATIONS Translate RotateScale Reflect We can use the Canvas class to apply various geometric transformations to the things that appear on the screen before we draw them.

12 GEOMETRIC TRANSFORMATION METHODS  We can apply a geometric transformation using the following Canvas methods:  rotate  translate  scale  skew  Every time we call one of these methods we add an operation to the current transformation. This transformation is then applied to all objects that are subsequently drawn on the View.  There are other methods besides the three we have listed here, but there is no “reflect” method. We achieve reflection by combining other operations (I’m going to explain how in a minute!).

13 GEOMETRIC TRANSFORMATIONS: AN EXAMPLE protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setColor(Color.RED); canvas.drawRect(0, 0,100, 100, paint); canvas.rotate(-135,100,100); canvas.scale(0.5f, 0.5f, 100, 100); paint.setColor(Color.BLUE); canvas.drawRect(0, 0, 100, 100, paint); } Note that this exactly the same rectangle as we drew before, but the current transformation will be applied before it is drawn. Add a rotation to the current transformation. N.B this has no effect on the graphics we have already drawn. Add a scale operation to the current transformation. Do Exercises 7 and 8

14 REFLECTION  The Canvas class does not have a specific “reflect” method. However  Reflection about a vertical line is the same as scaling by a factor of -1 in the x direction and +1 in the y direction.  Reflection about a line that passes through a point (a,b) at angle Θ can be expressed as a combination of a reflection in the vertical axis followed by a rotation of 2Θ clockwise about the point (a,b). Do Exercises 9 and 10

15 ADDING A CUSTOM VIEW TO AN XML FILE In Eclipse we can add a custom view to a layout file by simply dragging it from the palette. Do Exercise 11

16 ADDING A CUSTOM VIEW TO AN XML FILE <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world" /> <uk.ac.brookes.u08971_ex1_2_sep_2013.KaleidoView android:id="@+id/kaleidoView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" />

17 SETTING AND MEASURING THE DIMENSIONS OF A VIEW  In order to ensure that graphics are appropriately drawn, we generally need to measure and set the dimensions of the view. We do this by overriding the following View class method. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) The widthMeasureSpec parameter packs two pieces of information into one integer. These are: a)A value containing a possible width for the view. b)A value that tells you whether to treat that possible width, as an exact specification, or a maximum value, or something that can be simply ignored The overriden onMeasure method should examine the values of its parameters and then use the method setMeasuredDimension to specify the dimensions that it wants the View to have.

18 DIMENSIONS OF THE KALEIDOSCOPE VIEW  We will set up our Kaleidoscope View so that it is the biggest square that will fit onto the screen. The next slides explain how to do that. Kaleidoscope View

19 MAKING THE VIEW A SQUARE THAT FILLS AS MUCH SPACE AS IT CAN @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int size = Math.min(measureSize(widthMeasureSpec), measureSize(heightMeasureSpec)); setMeasuredDimension(size, size); } private int measureSize(int measureSpec) { int result; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); if (mode == MeasureSpec.EXACTLY) { result = DEFAULT_SIZE; } else { result = size; } return result; }

20 DRAWING A CIRCLE THAT FILLS THE VIEW @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int size = getMeasuredHeight(); paint.setColor(Color.DKGRAY); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); canvas.drawCircle(size/2, size/2, size/2, paint); } This method call gets the height of the View, which we previously set in the onMeasure method. This method call means that shapes will be drawn in outline, rather than filled. Do Exercise 12

21 DRAWABLE OBJECTS  We can draw on to a Canvas by directly calling methods such as drawCircle. However it is sometimes more convenient to represent figures to be drawn as separate objects.  Such objects must extend the abstract class Drawable. We draw them on the canvas by calling the method draw(Canvas canvas)  There are subclasses of Drawable that allow us to draw shapes, bitmaps, colour gradients, etc.

22 USING A SHAPEDRAWABLE @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int size = getMeasuredHeight(); paint.setColor(Color.DKGRAY); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); canvas.drawCircle(size/2, size/2, size/2, paint); ShapeDrawable oval; oval = new ShapeDrawable(new OvalShape()); oval.setBounds(size/6, size/4, 5*size/6, 3*size/4); oval.draw(canvas); } OvalShape is a class that represents ovals. N.B. It is not a good idea to instantiate objects within the onDraw method. We are doing it here just to keep the example simple. Do Exercise 13

23 HOW A KALEIDOSCOPE WORKS A standard kaleidoscope consists of a tube, containing two mirrors at an angle to one another. At the end of the tube there is an “object cell” or “object chamber” containing some visually appealing objects. In our case the objects will be coloured shapes. Object Cell Mirrors

24 HOW A KALEIDOSCOPE WORKS The mirrors demarcate a segment of the object cell. This segment is reflected several times in the mirrors to generate the image that you see. Mirrors

25 REPRESENTING THE OBJECT CELL  In our application we will represent the object cell as an ArrayList of Drawable objects.  The onDraw method will iterate through this list and draw each of the objects.  For simplicity we shall make all of our Drawable objects ovals, but we could put anything drawable into the ArrayList if we wanted.

26 SOME NEW FIELDS FOR THE VIEW CLASS private static final int NBR_OBJECTS = 450; private static final int MAX_OBJECT_SIZE = 20; private static final int MIN_OBJECT_SIZE = 10; private ArrayList objectCell = new ArrayList ();; private Random rand = new Random(); private int[] colors = {Color.BLUE, Color.RED, Color.BLACK, Color.CYAN, Color.MAGENTA}; The number of objects in the object cell Maximum and minimum size of objects in the object cell The object cell itself Colours for objects in the object cell

27 POPULATING THE OBJECT CELL public void initObjectCell() { int size = getMeasuredHeight(); for (int i = 0; i < NBR_OBJECTS; i++) { int x = rand.nextInt(size); int y = rand.nextInt(size); int h = MIN_OBJECT_SIZE + rand.nextInt(MAX_OBJECT_SIZE); int w = MIN_OBJECT_SIZE + rand.nextInt(MAX_OBJECT_SIZE); ShapeDrawable oval; oval = new ShapeDrawable(new OvalShape()); oval.setBounds(x, y, x + w, y + h); Paint ovalPaint = oval.getPaint(); ovalPaint.setColor(colors[rand.nextInt(colors.length)]); ovalPaint.setAlpha(128); objectCell.add(oval); } This makes the shapes semi- transparent.

28 WHEN DO WE POPULATE THE OBJECT CELL  The initObjectCell method in the previous slide calls getMeasuredHeight() in order to determine the height of the view.  This means we cannot call initObjectCell from the View’s constructor, because the View will not have been assigned a size at that point.  Instead we override the method onLayout. This method is called after the View has been assigned a size, and is used to layout the contents of the View. @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { initObjectCell(); }

29 DRAWING THE OBJECT CELL @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int size = getMeasuredHeight(); paint.setColor(Color.DKGRAY); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); canvas.drawCircle(size/2, size/2, size/2, paint); for (Drawable d: objectCell) { d.draw(canvas); } Note that some of our coloured ovals are outside of the area where the object cell ought to be. This does not matter because we are going to clip the View. Do Exercise 14

30 FINISHING THE APPLICATION 1. Clip the View so that only one segment is shown.

31 FINISHING THE APPLICATION 1.Clip the View so that only one segment is shown. 2.Apply a transformation representing reflection in one of the mirrors, then redraw. Mirrors

32 FINISHING THE APPLICATION 1.Clip the View so that only one segment is shown. 2.Apply a transformation representing reflection in one of the mirrors, then redraw. 3.Repeatedly refect in one mirror then the other until the Kaleidoscopic image is complete. Do Exercises 15-18

33 SUMMARY Concepts covered this week:  Obtaining a canvas  Drawing primitives  Clipping  Transformations  Drawable objects


Download ppt "David Sutton 2D GRAPHICS IN ANDROID. INTRODUCTION AND OUTLINE  In this week’s session we will create a simple Kaleidoscope application. Topics that will."

Similar presentations


Ads by Google