1 / 14

Graphics with Canvas,

Graphics with Canvas,. Approaches for Graphics. Load image from /res/ drawable Best for static images OpenGL ES 3D graphics (i.e., transforms such as spin can be applied to graphical objects ) Best for real animation Draw on Canvas or SurfaceView Canvas for drawing within the main thread

carlo
Download Presentation

Graphics with Canvas,

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Graphics with Canvas,

  2. Approaches for Graphics • Load image from /res/drawable • Best for static images • OpenGL ES • 3D graphics (i.e., transforms such as spin can be applied to graphical objects) • Best for real animation • Draw on Canvas or SurfaceView • Canvas for drawing within the main thread • SurfaceView is faster, and better for detailed graphics • Note, if your main thread take too long, the OS will kill it, and it will be difficult to debug.

  3. Drawable shapes • Make new app, edu.udel.eleg454.Graphics1 • In onCreate is setContentView(R.layout.main) • Instead of the view generated by R.layout.main, we use our own, which extends View • In Graphics1 class, add • private class MyView extends View { public MyView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { ShapeDrawablemDrawable = new ShapeDrawable(new OvalShape()); mDrawable.getPaint().setColor(0xff74AC23); mDrawable.setBounds(10, 10, 310, 60); mDrawable.draw(canvas); } } • Then, in onCreate, replace setContentView(R.layout.main); with setContentView(new MyView(this)); • Run • Besides BitMaps, OvalShape, ArcShape, PathShape, RoundRectShape, and Shape

  4. View Widget • The previous method required us to replace setContentView(R.layout.main); • This resulted in the entire view being controlled by our view object • E.g., we could not have a button in the view where we place the button with the layout editor • To fix this, we add a view widget • Move MyView to separate class • Make new class • In package explorer, under /src • Find edu.udel.eleg454.TestGraphics1 • Right click on edu.udel.eleg454.TestGraphics1 • Select: new->class • Dialog opens • Name: MyView • Superclass: View (then select browser to get full name: android.View) • OK • Move functions from private class MyView to this new MyView • Move public MyView( • MoveonDraw • Also, in MyView add public MyView(Context context, AttributeSetattrs) { super(context, attrs); }

  5. View Widget • Go to main.xml graphical layout editor • Drag button to the screen • Leave id as button1 • Go to main.xml (not the editor) • Find second <Button …> </Button> • Before<Button>, add • < edu.udel.eleg454.TestGraphics1.MyView android:layout_width="wrap_content" android:layout_height=“116dpt" android:id="@+id/View01"></ edu.udel.eleg454.TestGraphics1.MyView> • Note that edu.udel.eleg454.TestGraphics1.MyView is the name of the separate class. If another name is used, then this name should be changed • Save and go back to graphical view. There should be a box labeled MyView. Drag the box to make it larger • Run

  6. Canvas Drawing • Canvas has many drawing functions, e.g., drawPath(Path path, Paint paint) • In onDraw, add the following • Path: sequence of graphical objects • Path path = new Path(); • Make line between two points • path.moveTo(10,10); // starting place • path.lineTo(160,160); • add circle somewhere • path.addCircle(160,160,20, Path.Direction.CCW); • Paint – for setting color and line width • Paint paint = new Paint(); • paint.setDither(true); • paint.setColor(Color.RED); • paint.setStyle(Paint.Style.FILL_AND_STROKE); • paint.setStrokeJoin(Paint.Join.ROUND); • paint.setStrokeCap(Paint.Cap.ROUND); • paint.setStrokeWidth(10); • Draw view canvas.drawPath(path, paint); • run

  7. Change graphics • At the end of TestGraphics1Activity.onCreate • MyViewmyView = (MyView) findViewById(R.id.View01); • Button button = (Button)findViewById(R.id.button1); • button.setOnClickListener(new View.OnClickListener() {}); • Let eclipse add unimplemented methods • In onClick, add • myView.redraw(); • In MyView • Add class variable • int radius = 20; • In onDraw, change • path.addCircle(160,160, 20, Path.Direction.CCW); • To • path.addCircle(160,160,radius, Path.Direction.CCW); • Add function • public void redraw() { • radius = 80; • invalidate(); // this is needed to force redraw • } • run

  8. notes • Use invalidate() to force redraw • In TestGraphics, add variable • MyViewmyView; • In TestGraphics.onCreate(), add • myView = (MyView) findViewById(R.id.View01); • Then myView.invalidate(); will force redraw • Is canvas documentation for more graphics • E.g., drawBitmap has several functions • Avoid declaring and setting variables in onDraw, instead, setting them elsewhere and access them from draw • Use invalidate() to force redraw • Use SurfaceView for faster screen drawing

  9. SurfaceView • Faster • You can draw on a SurfaceView from other threads, not just to UI thread • When drawing with the UI thread, if the drawing takes a long time, then everything else must wait for the drawing to complete, • e.g., the user cannot press any buttons • If you put a long activity in the UI thread, a message will pop up saying that the app has stopped responding • If you put a long drawing activity when starting the app, the system just kill it (thinking that it did not start correctly) • But, SurfaceViews are not transparent, nothing behind the view can be seen • Differences • In Canvas approach, your draw function is called and has argument canvas. You can draw on this canvas. You can force a redraw can calling invalidate. • Invalidate will result in onDraw being called from the UI thread • With surfaceview, you get a canvas and can draw on it whenever you want. Usually you draw on it from a new thread • E.g., You start the thread from the UI thread

  10. SurfaceViewFun • Make a new app, SurfaceViewFun and package name edu.udel.eleg454.SurfaveViewFun • Make new class • Right click on edu.udel.eleg454.SurafceViewFun • Select New -> class • Name: MySurfaceView • SuperClass: SurfaceView • Go to res/layout/main.xml • Open graphical view • Click on “Advanced” • Drag SurfaceView • In xml view, find the <SurfaceView …. • Change <SurfaceView … to <edu.udel.eleg454.SurfaceViewFun.MyView. • Go back to graphical view and check that the surfaceView is now labeled MySurfaceView. If not, then something is wrong.

  11. MySurfaceView • Open MySurfaceView • Eclipse will ask to implement some function. Add all three of these • public MySurfaceView(Context context, AttributeSetattrs, intdefStyle) • public MySurfaceView(Context context, AttributeSetattrs) { • public MySurfaceView(Context context) { • Each on has content • super(context, attrs); // eclipse migth add this part • ini(context); // a function to make

  12. Change • public class MySurfaceView extends SurfaceView • To • public class MySurfaceView extends SurfaceViewimplements SurfaceHolder.Callback • Add unimplements functions

  13. Thread class • Make new subclass in MySurfaceView and extend Thread, i..e, add • Class MyThread extends Thread {}; • This will be the thread we use for drawing • We will draw an oval, by the drawing is slightly animated • In MyThread, add member variables • SurfaceHoldersurfaceHolder = null; // this a key variable as it allow use to get a canvas • boolean done; • long lastTime, startTime; • Canvas canvas; • RectFrectForOval = null; • float duration = 5*1000; • Paint drawingPaint; • float arcSweep;

  14. MyThread member functions • Constructor • public MyThread(SurfaceHolder _surfaceHolder) { • surfaceHolder = _surfaceHolder; • drawingPaint = new Paint(); • drawingPaint.setColor(Color.BLUE); • } • We will draw an oval, but it will • This is the function that will run in the thread. • @Override • public void run() { • Log.e("surface","running thread"); • setOval(); • lastTime = System.currentTimeMillis(); • startTime = System.currentTimeMillis(); • done=false; • while (!done) { • updateArcSweep(); • drawCurrentArc(); • } • Log.e("SurfaceViewFun","MyThread.run has finished"); • }

More Related