Draw Circle on Canvas Java
Overview
Let'southward have a wait at edifice a custom view that allows the user to pigment on the screen past pressing down 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 unproblematic 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= "truthful" android:layout_alignParentTop= "truthful" /> </RelativeLayout> Elementary Cartoon with Canvas
Allow'southward endeavor drawing a couple of circles on screen. This requires united states to ascertain a Paint object which controls the styling and color of what is fatigued. Permit's start by preparing the pigment:
public class SimpleDrawingView extends View { // setup initial color private terminal int paintColor = Color . Black ; // defines pigment and sheet individual Pigment drawPaint ; public SimpleDrawingView ( Context context , AttributeSet attrs ) { super ( context , attrs ); setFocusable ( true ); setFocusableInTouchMode ( truthful ); setupPaint (); } // Setup pigment with color and stroke styles individual void setupPaint () { drawPaint = new Paint (); drawPaint . setColor ( paintColor ); drawPaint . setAntiAlias ( truthful ); drawPaint . setStrokeWidth ( v ); drawPaint . setStyle ( Paint . Manner . STROKE ); drawPaint . setStrokeJoin ( Paint . Join . Round ); drawPaint . setStrokeCap ( Paint . Cap . Round ); } } At present that we take the paint setup to take a black color and configured a particular stroke manner, let'due south endeavor to describe a few circles with different 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 course SimpleDrawingView extends View { // ...variables and setting up pigment... // Let'south draw three circles @Override protected void onDraw ( Sail canvas ) { canvass . drawCircle ( 50 , fifty , xx , drawPaint ); drawPaint . setColor ( Colour . Green ); canvas . drawCircle ( fifty , 150 , 20 , drawPaint ); drawPaint . setColor ( Color . BLUE ); canvas . drawCircle ( l , 250 , 20 , drawPaint ); } } Observe that onDraw passes usa a sheet object which we use to describe leveraging the Pigment nosotros divers earlier. The drawCircle method accepts the x, y and radius of the circumvolve in add together-on to the paint. This renders the following:
Treatment Bear upon Interactions
Suppose at present we wanted to describe a circumvolve every fourth dimension the user touches downwards on the drawing view. This would crave us to keep runway of an array of points for our circles and so append a betoken for each onTouch event triggered:
public course SimpleDrawingView extends View { // setup initial color private terminal int paintColor = Color . Black ; // defines paint and canvas private Paint drawPaint ; // Store circles to describe each time the user touches downwardly individual List < Signal > circlePoints ; public SimpleDrawingView ( Context context , AttributeSet attrs ) { super ( context , attrs ); setupPaint (); // same as before circlePoints = new ArrayList < Betoken >(); } // Depict each circle onto the view @Override protected void onDraw ( Sail sail ) { for ( Point p : circlePoints ) { canvas . drawCircle ( p . 10 , p . y , 5 , drawPaint ); } } // Append new circumvolve each time user presses on screen @Override public boolean onTouchEvent ( MotionEvent issue ) { bladder touchX = event . getX (); float touchY = result . getY (); circlePoints . add together ( new Point ( Math . round ( touchX ), Math . round ( touchY ))); // signal view should be redrawn postInvalidate (); render truthful ; } individual void setupPaint () { // same as earlier drawPaint . setStyle ( Paint . Mode . Fill ); // modify to fill // ... } } with this, a black circumvolve is drawn each time we printing downward:
Drawing with Paths
So far we take explored the onDraw method of a view and we were able to depict circles onto the view based on touch interactions with the view. Side by side, let'southward meliorate our drawing application past removing the list of circles and instead cartoon with paths. The Path course is platonic for allowing the user to draw on screen. A path can contain many lines, contours and fifty-50 other shapes. First, let'south add a Path variable to rails our cartoon:
public class SimpleDrawingView extends View { // ... individual Path path = new Path (); // ... } Side by side, permit'south suspend points to the path equally the user touches the screen. When the user presses down, allow'southward start a path and then when they elevate let'south connect the points together. To exercise this, nosotros need modify the onTouchEvent to suspend these points to our Path object:
public class SimpleDrawingView extends View { individual Path path = new Path (); // Become 10 and y and append them to the path public boolean onTouchEvent ( MotionEvent event ) { bladder pointX = outcome . getX (); bladder pointY = event . getY (); // Checks for the issue that occurs switch ( effect . getAction ()) { instance MotionEvent . ACTION_DOWN : // Starts a new line in the path path . moveTo ( pointX , pointY ); suspension ; case MotionEvent . ACTION_MOVE : // Draws line between terminal bespeak and this point path . lineTo ( pointX , pointY ); suspension ; default : render false ; } postInvalidate (); // Signal view should exist redrawn return truthful ; // Indicate we've consumed the affect } // ... } then let's alter 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 ( Sail canvas ) { sail . drawPath ( path , drawPaint ); } individual void setupPaint () { // same equally before drawPaint . setStyle ( Pigment . 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 cartoon onto a sheet, yous can ofttimes significantly ameliorate render times by caching the paradigm into a bitmap as outlined in this stackoverflow mail.
Bitmap mField = null ; public void init () { mField = new Bitmap (... dimensions ...); Sheet c = new Canvas ( mField ); c . drawRect (...); ... } public void onDraw ( Sheet c ) { c . drawBitmap ( mField ); } This is a mutual design for improving cartoon 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 grade SimpleDrawingView extends View { // setup initial colour private final int paintColor = Colour . BLACK ; // defines paint and sail private Paint drawPaint ; // stores next circumvolve 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 Paint (); drawPaint . setColor ( paintColor ); drawPaint . setAntiAlias ( true ); drawPaint . setStrokeWidth ( five ); drawPaint . setStyle ( Paint . Fashion . STROKE ); drawPaint . setStrokeJoin ( Pigment . Join . Round ); drawPaint . setStrokeCap ( Paint . Cap . Round ); } @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 ( event . getAction ()) { case MotionEvent . ACTION_DOWN : path . moveTo ( pointX , pointY ); return true ; instance MotionEvent . ACTION_MOVE : path . lineTo ( pointX , pointY ); suspension ; default : render simulated ; } // Forcefulness a view to draw once more postInvalidate (); return truthful ; } } Cartoon with Density Contained Pixels
When drawing or animative, you oft want to draw using density independent pixels in order to exist robust to dissimilar device sizes and densities. You may likewise want to determine the device peak or width in order to describe intelligently. Copy this DeviceDimensionsHelper.java utility course to DeviceDimensionsHelper.coffee in your project and use anywhere that yous lot accept a context to make up one's mind 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 ); // Convert dp to pixels bladder px = DeviceDimensionsHelper . convertDpToPixel ( 25 f , this ); // Convert pixels to dp bladder dp = DeviceDimensionsHelper . convertPixelsToDp ( 25 f , this ); You can then utilise this to exercise smarter drawing for more than responsive custom views.
Source: https://youngbefordow.blogspot.com/2022/04/android-studio-canvas-draw-circle.html
Post a Comment for "Draw Circle on Canvas Java"