Android Studio Canvas Draw Circle
Overview
Let's have a look at edifice a custom view that allows the user to pigment on the screen by pressing downwardly their finger. This will illustrate how to build custom components, how to describe shapes and paths on a view and as well how to handle user impact interactions.
Creating our Custom View
Create a uncomplicated class for drawing that extends View called SimpleDrawingView
:
public class SimpleDrawingView extends View { public SimpleDrawingView ( Context context , AttributeSet attrs ) { super ( context , attrs ); } }
Add this to the XML layout for activity so our custom view is embedded within:
<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" > <com.codepath.instance.simpledrawapp.SimpleDrawingView android:id= "@+id/simpleDrawingView1" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_alignParentBottom= "true" android:layout_alignParentLeft= "truthful" android:layout_alignParentRight= "true" android:layout_alignParentTop= "true" /> </RelativeLayout>
Simple Cartoon with Canvas
Allow's endeavor drawing a couple of circles on screen. This requires united states to define a Pigment
object which controls the styling and color of what is fatigued. Let's start by preparing the pigment:
public class SimpleDrawingView extends View { // setup initial color private final int paintColor = Color . Black ; // defines paint and sheet private Paint drawPaint ; public SimpleDrawingView ( Context context , AttributeSet attrs ) { super ( context , attrs ); setFocusable ( true ); setFocusableInTouchMode ( true ); setupPaint (); } // Setup pigment with color and stroke styles individual void setupPaint () { drawPaint = new Paint (); drawPaint . setColor ( paintColor ); drawPaint . setAntiAlias ( true ); drawPaint . setStrokeWidth ( 5 ); drawPaint . setStyle ( Paint . Manner . STROKE ); drawPaint . setStrokeJoin ( Paint . Bring together . Circular ); drawPaint . setStrokeCap ( Paint . Cap . ROUND ); } }
Now that we accept the pigment setup to have a black color and configured a particular stroke style, let's endeavor to describe a few circles with dissimilar colors. All cartoon that happens in a view should take place within the onDraw
method which is automatically called when a view is rendered:
public class SimpleDrawingView extends View { // ...variables and setting up paint... // Let's draw iii circles @Override protected void onDraw ( Sail canvas ) { canvas . drawCircle ( 50 , 50 , 20 , drawPaint ); drawPaint . setColor ( Colour . Dark-green ); canvas . drawCircle ( 50 , 150 , 20 , drawPaint ); drawPaint . setColor ( Color . BLUE ); canvas . drawCircle ( l , 250 , 20 , drawPaint ); } }
Notice that onDraw
passes us a canvass
object which we use to draw leveraging the Pigment
nosotros defined earlier. The drawCircle
method accepts the x, y and radius of the circumvolve in add-on to the paint. This renders the following:
Handling Touch Interactions
Suppose at present we wanted to draw a circle every fourth dimension the user touches downwards on the drawing view. This would crave us to keep runway of an assortment of points for our circles and then append a point for each onTouch
event triggered:
public course SimpleDrawingView extends View { // setup initial color private terminal int paintColor = Color . Blackness ; // defines paint and canvas private Paint drawPaint ; // Store circles to draw each time the user touches down private List < Signal > circlePoints ; public SimpleDrawingView ( Context context , AttributeSet attrs ) { super ( context , attrs ); setupPaint (); // same as before circlePoints = new ArrayList < Betoken >(); } // Draw each circle onto the view @Override protected void onDraw ( Canvas canvas ) { for ( Point p : circlePoints ) { canvas . drawCircle ( p . x , p . y , 5 , drawPaint ); } } // Append new circle each time user presses on screen @Override public boolean onTouchEvent ( MotionEvent effect ) { float touchX = event . getX (); float touchY = event . getY (); circlePoints . add ( new Indicate ( Math . circular ( touchX ), Math . round ( touchY ))); // signal view should be redrawn postInvalidate (); return true ; } private void setupPaint () { // same as before drawPaint . setStyle ( Pigment . Mode . Fill ); // change to fill // ... } }
with this, a black circle is drawn each time we printing down:
Cartoon with Paths
So far we take explored the onDraw
method of a view and we were able to draw circles onto the view based on touch interactions with the view. Next, let'southward ameliorate our cartoon awarding past removing the list of circles and instead cartoon with paths. The Path class is platonic for allowing the user to draw on screen. A path can contain many lines, contours and fifty-fifty other shapes. First, let's add together a Path
variable to rail our cartoon:
public form SimpleDrawingView extends View { // ... private Path path = new Path (); // ... }
Side by side, let's suspend points to the path equally the user touches the screen. When the user presses downwards, let's start a path and then when they elevate let'southward connect the points together. To practice this, we need modify the onTouchEvent
to append these points to our Path object:
public class SimpleDrawingView extends View { private Path path = new Path (); // Get ten and y and append them to the path public boolean onTouchEvent ( MotionEvent event ) { bladder pointX = outcome . getX (); float pointY = event . getY (); // Checks for the outcome that occurs switch ( effect . getAction ()) { case MotionEvent . ACTION_DOWN : // Starts a new line in the path path . moveTo ( pointX , pointY ); suspension ; case MotionEvent . ACTION_MOVE : // Draws line betwixt terminal bespeak and this point path . lineTo ( pointX , pointY ); break ; default : render false ; } postInvalidate (); // Point view should exist redrawn return true ; // Indicate we've consumed the affect } // ... }
then let's change the onDraw
to remove the circles and instead to render the lines nosotros have plotted in our path:
public class SimpleDrawingView extends View { // ... onTouchEvent ... // Draws the path created during the touch events @Override protected void onDraw ( Canvas sheet ) { sail . drawPath ( path , drawPaint ); } individual void setupPaint () { // same equally before drawPaint . setStyle ( Paint . Style . STROKE ); // alter back to stroke // ... } }
and with that, we have a very basic painting app that looks like:
Efficient Drawing with Bitmap Cache
When drawing onto a canvas, you can ofttimes significantly improve render times past caching the image into a bitmap as outlined in this stackoverflow mail.
Bitmap mField = null ; public void init () { mField = new Bitmap (... dimensions ...); Canvas c = new Canvas ( mField ); c . drawRect (...); ... } public void onDraw ( Canvas c ) { c . drawBitmap ( mField ); }
This is a common pattern for improving drawing functioning.
Reference for SimpleDrawingView
The full source lawmaking for our SimpleDrawingView
:
package com . codepath . example . simpledrawapp ; import android.content.Context ; import android.graphics.Sail ; import android.graphics.Color ; import android.graphics.Paint ; import android.graphics.Path ; import android.util.AttributeSet ; import android.view.MotionEvent ; import android.view.View ; public class SimpleDrawingView extends View { // setup initial color private terminal int paintColor = Color . BLACK ; // defines paint and canvass private Paint drawPaint ; // stores next circle private Path path = new Path (); public SimpleDrawingView ( Context context , AttributeSet attrs ) { super ( context , attrs ); setFocusable ( true ); setFocusableInTouchMode ( true ); setupPaint (); } private void setupPaint () { // Setup paint with color and stroke styles drawPaint = new Pigment (); drawPaint . setColor ( paintColor ); drawPaint . setAntiAlias ( true ); drawPaint . setStrokeWidth ( 5 ); drawPaint . setStyle ( Paint . Style . STROKE ); drawPaint . setStrokeJoin ( Paint . Join . Round ); drawPaint . setStrokeCap ( Paint . Cap . Circular ); } @Override protected void onDraw ( Canvas canvas ) { sheet . drawPath ( path , drawPaint ); } @Override public boolean onTouchEvent ( MotionEvent event ) { float pointX = event . getX (); float pointY = effect . getY (); // Checks for the event that occurs switch ( outcome . getAction ()) { case MotionEvent . ACTION_DOWN : path . moveTo ( pointX , pointY ); return true ; case MotionEvent . ACTION_MOVE : path . lineTo ( pointX , pointY ); break ; default : render false ; } // Force a view to describe once more postInvalidate (); return true ; } }
Drawing with Density Independent Pixels
When drawing or animating, you often desire to draw using density independent pixels in order to exist robust to dissimilar device sizes and densities. Yous may likewise desire to determine the device summit or width in order to draw intelligently. Re-create this DeviceDimensionsHelper.java utility form to DeviceDimensionsHelper.java
in your project and use anywhere that you lot accept a context to determine screen dimensions or practise translations between dp
and px
:
// Become height or width of screen int screenHeight = DeviceDimensionsHelper . getDisplayHeight ( this ); int screenWidth = DeviceDimensionsHelper . getDisplayWidth ( this ); // Catechumen dp to pixels bladder px = DeviceDimensionsHelper . convertDpToPixel ( 25 f , this ); // Convert pixels to dp float dp = DeviceDimensionsHelper . convertPixelsToDp ( 25 f , this );
Yous tin then utilise this to exercise smarter drawing for more responsive custom views.
Source: https://guides.codepath.com/android/Basic-Painting-with-Views
0 Response to "Android Studio Canvas Draw Circle"
Post a Comment