How to Draw a Circle in Android Studio
Did you ever desire to create highly-customized user interfaces in Android? And so this is the tutorial for you!
To draw custom shapes, yous demand to go along iterating until you achieve the beautiful art you desire. In this tutorial, you'll learn how to depict your design on newspaper outset to avoid wasting time via trial and error.
You'll improve an app called Stars of Science. Yous'll learn how to create custom shapes past painting a profile card with a curved custom shape and gradient colors.
Throughout the tutorial, yous'll learn how to:
- Prepare a custom shape on paper before coding.
 - Extend the Android            
Viewto describe and paint it on theCanvas. - Draw a curved shape in gradient colors.
 
The custom shape you'll create volition expect like this:
          
        
Note: This tutorial assumes yous empathize the basics of Android development with Kotlin. If yous're new to Android development, please go through Beginning Android Development with Kotlin to understand the basics. If you're new to Kotlin, check out this Introduction to Kotlin tutorial.
Getting Started
Download the project materials past clicking the Download Materials button at the superlative or bottom of this tutorial. Launch Android Studio 3.6.i or later and select Open an existing Android Studio project. Then navigate to and select the starter project binder where yous'll find the files you need to kickoff, along with some widgets.
Your app already has its basic UI set upwards then you tin focus on drawing custom shapes in Android.
Build and run the app. You'll encounter the following screen on your mobile phone or Android emulator:
          
        
It's not bad, but the pinnacle of the carte du jour doesn't accept much pizazz. You'll change that throughout the tutorial.
Exploring the Project
Take a quick look at the project structure. Expand starsofscience bundle and bank check out the folders within:
          
        
Here'southward a breakdown of the folders:
- utils contains four files with extension functions yous'll use in your painting journey.
 -             view            contains            
CircularImageViewwhich yous'll use to brandish the avatar in a round shape. The code inside this class is out of the scope of this tutorial. -             starsofscience            contains three files:            
- MainActivity.kt is the app's main and luncher activeness.
 - Painter.kt contains pigment() which you'll implement to paint your custom shape. You'll add together all cartoon and painting logic to this part.
 -                 CustomPainter.kt                is a custom Android                View                with a constructor accepting the width and height of your custom shape in addition to a painter object that has all the drawing and painting logic. This                
CustomPainteroverridesonDraw()and delegates all the drawing to the painter by executingsheet?.let(painter::paint). 
 
Now that you know more about the classes you'll piece of work with have a moment to learn some of the theory behind making beautiful shapes.
Coding Your Shapes
Earlier diving into drawing with Android          Canvas, you need to know which tools you'll need, how to use them and how to ready to lawmaking your target shape.
Think about drawing in the concrete globe. To draw a shape, y'all need to go a pencil and newspaper and and so utilize your manus to move the pencil across the paper's surface. Finally, if you desire to make information technology beautiful, you need to get a brush with some paint.
In this department, you'll start by drawing a shape freehand. Grab a pencil and paper and become ready!
Know Your Canvas
Your canvas acts every bit the digital version of the piece of paper you draw on. It holds all your drawing elements, including lines, curves, arches, shapes, text and images.
The sail needs a size, including width and peak. Drawing on a sail without knowing its size tin lead to unexpected results.
On your paper, before drawing any shape, define the sheet by drawing a rectangle of any size y'all want. Whatever shapes you describe later will exist relative to that canvas.
          
        
Note: You lot don't want your shapes to have an absolute position or size. Instead, brand them relative to the size of the sail. This lets you display your shapes on unlike devices with different screen sizes.
For instance, you might place your shape at the center of the canvas or make its size equal to one-half of the canvas size.
Now that you have a canvas, it'southward time to create a shape.
Defining How to Movement Your Pencil
In visual arts, you have to move your pencil properly across the newspaper'due south surface to create your artwork. Yous'll employ the aforementioned mechanism to depict on the canvas.
Before yous can draw a shape, y'all need to consider which functionalities the canvas object needs to have.
For instance, if you want to depict a foursquare, y'all need to draw four lines. So, you need the drawing line function in your framework. On the other hand, if you want to draw a crescent, yous need to draw two curves with the drawing curve function.
Option up your pencil and describe a circumvolve in the eye of the circle that's a quarter of the width, similar this:
          
        
Now, to convert that shape on your paper into a shape in Android, you need to consider its coordinates.
Calculating Coordinates
Coordinates are pairs of numbers that ascertain the exact location of a point on a plane.
Before yous depict anything, you need to know the main points that brand up that shape. For proficient practice, summate all the coordinates and dimensions on your newspaper before writing any code. This saves you lot coding time and makes you focus on translating that shape from the paper onto your device.
Since you already drew a circumvolve relative to the canvas on your paper, you lot already calculated two things:
-             The center of the circle: Since your circle is at the center of the canvas, the middle of the circle is the centre of the canvas. And then the            ten            coordinate of the circle'southward center is equal to one-half of the width of the canvas and the            y            coordinate of the circle'southward center is equal to half of the acme of the canvass. This means that:
cx = canvas width / ii
cy = canvass acme / 2 -             The radius: Since your circumvolve is a quarter of the canvas width, the diameter of the circle is equal to a quarter of the width of the canvas. The radius is equal to one-half of the diameter. That means:
diameter = canvas width / 4
radius = bore / 2 = canvas width / eight 
          
        
See, cartoon your shapes on paper helps y'all summate the points you need to draw your shape relative to the canvas.
It'due south efficient to visualize what you need to practise before it's time to translate your ideas into lawmaking. Making paper sketches is a prerequisite for your custom drawing! :]
Using CustomPainter
Now that yous've learned some theory, it's time to start using the Android          Canvas          and add some code that will reproduce your cartoon in the app.        
Implementing the Painter Interface
Start by creating a new course          ProfileCardPainter          in the          starsofscience          package. And so replace the whole file content with:
package com.raywenderlich.android.starsofscience  import android.graphics.* import androidx.annotation.ColorInt  //1 course ProfileCardPainter(     //2     @ColorInt individual val color: Int ) : Painter {   //three   override fun paint(canvas: Canvas) {    } }                Here you:
- Ascertain a new class named            
ProfileCardPainterthat implements the interfacePainter. - Then in its primary constructor you define the profile color equally a class belongings.
 - Finally, you implement            
paint(canvas: Canvas).CustomPainterwill phone call this method whenever the object needs to pigment.You'll write all your cartoon code inside this function, which gives you lot i parameter: The
canvasto describe on. 
Rendering With CustomPainter
Go to          MainActivity.kt. You'll find the post-obit line of code in          onCreate():
profileCardContainer.setBackgroundColor(R.color.colorPrimary.toColorInt(this))                Information technology sets a background color to the          profileCardContainer          which is a          FrameLayout          already divers in XML. You don't need that line anymore considering yous want to add your custom shape instead of that solid color.
Replace that line with the post-obit code:
//1 val azureColor = R.color.colorPrimary.toColorInt(this) val avatarRadius = R.dimen.avatar_radius.resToPx(this) val avatarMargin = R.dimen.avatar_margin.resToPx(this) val cardWidth = ViewGroup.LayoutParams.MATCH_PARENT val cardHeight = R.dimen.profile_card_height.resToPx(this).toInt() //2 val painter = ProfileCardPainter(   color = azureColor ) //3 profileCardContainer.addView(   CustomPainter(     context = this,     width = cardWidth,     top = cardHeight,     painter = painter   ) )                Add whatever missing import by pressing Choice+Enter on Mac or Alt+Enter on PC.
In the code to a higher place:
- You define the properties of your custom shape: Colour, avatar radius, avatar margin, width and height.
 - Then, you create a            
ProfileCardPainterwith the color y'all previously divers. - Finally, you add together a new            
CustomPainteras a subview ofprofileCardContainerby passing all its needed properties:-                 
contextto create this custom AndroidView. -                 
widthandheightof the custom shape. -                 
painterresponsible for all the drawing logic. 
 -                 
 
Build and run the app to see… a pretty ugly card because you oasis't drawn anything notwithstanding. Don't worry, yous'll start drawing something in a moment. :]
          
        
Drawing Your First Shape
In this section, y'all'll practice with the tools you need to describe in the computer graphics globe. They're a lot like the concrete tools you used to depict a circle on a paper. Then, with this cognition, you lot'll draw your first shape!
Note: Graphics libraries have similar APIs for drawing, which makes cartoon in Android comparable to drawing in iOS, Flutter and the spider web. When you master drawing custom shapes on 1 platform, information technology's like shooting fish in a barrel to reuse this knowledge on other platforms.
Drawing and Painting a Rectangle
To draw a rectangle, you demand to create a          RectF          object with the size you lot desire. You then demand a          Pigment          object with the color you adopt to start drawing that          RectF          on the canvass.
          RectF          is a simple grade with iv immutable          float          properties: Left, top, right and bottom. These 4 numbers represent a rectangle, where:
- Left is the left-well-nigh point on the x-axis.
 - Summit is the top-most point on the y-centrality.
 - Right is the right-nearly betoken on the 10-centrality.
 - Lesser is the lesser-nigh point on the y-axis.
 
            Annotation: You can calculate any actress backdrop in            RectF, like the width and tiptop, based on these four main backdrop.          
In this tutorial, yous'll rely on            RectF            for your shape premises. You'll depict each shape inside of and based on a certain            RectF.          
In          ProfileCardPainter.kt, get to          paint()          and add together the post-obit:
//1 val width = sheet.width.toFloat() val height = canvass.height.toFloat() //2 val shapeBounds = RectFFactory.fromLTWH(0f, 0f, width, height) //iii val pigment = Paint() pigment.color = color //four canvas.drawRect(shapeBounds, pigment)                Add together any missing import by pressing Option+Enter on Mac or Alt+Enter on PC.
Hither'south what this code defines:
- The            
widthandheightof the canvas. -             
shapeBoundsis aRectFwith a size that fits the whole area of the canvas by using the factory functionfromLTWH(). -             
paintis your paint and its colour. - Finally, y'all depict your            
shapeBoundson thecanvasby passing it todrawRect()forth with yourpaintfrom the previous line. 
Now, build and run the app. Meet that the card now has a blue rectangle every bit its background. Hooray, you've drawn your first shape! :]
          
        
That's improve, but there'south still much room for improvement!
Using a Path to Draw the Profile Card
A path is not a bitmap or raster, and it doesn't have pixels. Information technology's an outline that represents a series of polish lines, arcs or Bézier curves. Using a path makes your shapes scalable and independent of the screen's resolution.
          Path          is a powerful class that y'all can use in many situations. For example, you tin prune a bitmap past a path, or y'all can use a path to draw a custom shape like you're nearly to do right now.
Drawing the Profile Carte du jour
In this department, you'll offset using the          Path          class to draw a more complex shape like the blueish shape hither:
          
        
But before yous start, you need to do some preparation.
There are a few things you should note in the previous image:
- Black dashed rectangle: Represents the whole canvas.
 - Ruby dashed rectangle: Marks the bounds of the blue shape. It has the same width and tiptop equally the sail, except that you decrease the avatar radius from its height.
 - Blueish shape: A rectangle with a half circle, an arc of a circumvolve, as a negative space at the bottom center. This arc should have a radius equal to the radius of the avatar.
 
Note: An arc is a segment of a bend. In this case, the arc you'll utilise is a section of a circle's circumference, also called a circular arc.
The epitome below shows a blue arc that starts at the zero degree angle and sweeps to xc degrees.
          
        
Beginning, go the radius of the avatar. Start by calculation a new grade property called          avatarRadius          to your          ProfileCardPainter          master constructor:
class ProfileCardPainter(     @ColorInt private val color: Int,     private val avatarRadius: Bladder ) : Painter {                Then, go to          MainActivity.kt          and, in          onCreate(), pass the          avatarRadius          to          ProfileCardPainter:
val painter = ProfileCardPainter(   color = azureColor,   avatarRadius = avatarRadius )                Finally, return to          ProfileCardPainter.kt          and update the          shapeBounds          by subtracting the          avatarRadius          from its pinnacle in          fromLTWH():
val shapeBounds = RectFFactory.fromLTWH(0f, 0f, width, height - avatarRadius)                          
        
To run into the results build and run the app:
          
        
Smashing! Now the blue background stops halfway downward the length of the avatar.
Adding Negative Space Around the Avatar
Next, you'll add some negative space to the blue shape to set information technology apart from the avatar. Add a new function called          drawBackground()          to          ProfileCardPainter:
            private fun drawBackground(canvas: Canvas, bounds: RectF, avatarBounds: RectF) {   //1   val paint = Paint()   paint.colour = color    //ii   val backgroundPath = Path().utilise {     // iii     moveTo(bounds.left, bounds.top)     // 4     lineTo(bounds.bottomLeft.x, bounds.bottomLeft.y)     // five     lineTo(avatarBounds.centerLeft.x, avatarBounds.centerLeft.y)     // 6     arcTo(avatarBounds, -180f, 180f, imitation)     // 7     lineTo(bounds.bottomRight.x, bounds.bottomRight.y)     // 8     lineTo(bounds.topRight.ten, bounds.topRight.y)     // 9     close()    }    //10   canvass.drawPath(backgroundPath, paint); }                Add whatever missing import past pressing          Option+Enter          on Mac or          Alt+Enter          on PC. To import all the extension functions you need for          RectF          in a row, add the following import:
import com.raywenderlich.android.starsofscience.utils.*                This diagram illustrates the proper coordinates for each point you demand to build the path.
          
        
In the previous lawmaking:
- You create a            
Paintobject and set its color. - And so, you create a            
Pathobject. - Yous movement to the top-left corner, P1, without drawing a line. This is like moving a pencil to a starting point without touching the paper.
 - Next, you add a directly line that starts at P1 and ends at P2.
 - Then, you lot add together a direct line that starts at P2 and ends at P3: The betoken at the edge of where you will beginning cartoon the arc.
 - Then, starting from            P3, add an arc in the upper half region of the avatar bounds: The arc starts from the angle            
-180degrees and sweeps by180degrees ending at P4.
You passfalseas the final parameter to forbid starting a new sub-path for the arc. This tells Android that y'all want the arc on the same path. - Side by side, you lot add a straight line that starts from the current indicate and ends at P5 at the lesser-right corner.
 - You cease past adding a straight line that starts from the electric current bespeak P5 and ends at the given bespeak P6 at the top-right corner.
 - Then you shut the path by adding a directly line that starts at the current point P6 and ends at the beginning betoken on the path, P1.
 - Finally, you draw the            
backgroundPathon the sheet past passing it todrawPath()withpaint. 
In the previous code, you can plummet lines 5 and six in a single line. Practice you know how? You can find the solution in the spoiler below.
[spoiler title="Solution"]
          You lot can collapse lines five and six by leaving simply line half dozen.        
arcTo(avatarBounds, -180f, 180f, fake)        The official documentation of
          arcTo(RectF oval, bladder startAngle, float sweepAngle, boolean forceMoveTo)        
states:          "If the start of the path is different from the path's current final bespeak, then an automatic            lineTo()            is added to connect the current contour to the get-go of the arc."          
          [/spoiler]
Phew! That was a lot of code, but it was worth the attempt!
Creating the Rectangle Around the Avatar
In          ProfileCardPainter, get to          paint()          and replace the last three lines:
          val paint = Pigment()     paint.color = color     canvas.drawRect(shapeBounds, paint)                with the following code to create a new          RectF          effectually the avatar:
//1 val centerAvatar = PointF(shapeBounds.centerX(), shapeBounds.lesser) //2 val avatarBounds = RectFFactory.fromCircle(center = centerAvatar, radius = avatarRadius) //3 drawBackground(canvas, shapeBounds, avatarBounds)                Hither's what this lawmaking does:
- You create a            
PointFobject for the center betoken of the avatar, wherexis theshapeBounds.centerX()andyis thebottomof theshapeBounds. - And so, you create a            
RectFobject from the avatar circle usingfromCircle(). The center iscenterAvatar, which you lot simply created, and the radius is theavatarRadius. - Finally, y'all call            
drawBackground()and laissez passer the canvas with rest of the parameters to draw your first path. 
Build and run the app. You'll meet this:
          
        
Y'all probably don't observe the difference withal. Don't worry, y'all'll gear up that side by side.
Calculation a Margin Around the Avatar
In that location is a divergence, but yous can't see it because the negative space is exactly equal to the circular avatar'southward size. Next, you'll brand that negative space a fleck bigger to leave a margin between it and the avatar.
First, go the margin of the avatar. Kickoff by adding one more course property called          avatarMargin          to your          ProfileCardPainter          master constructor, don't forget the comma at the end of the line above the new code.
class ProfileCardPainter(     ...     individual val avatarMargin: Float )                Then, become to          MainActivity.kt          and, in          onCreate(), pass the          avatarMargin          to the          ProfileCardPainter          constructor:
val painter = ProfileCardPainter(   ...   avatarMargin = avatarMargin )                Finally, return to          ProfileCardPainter.kt          and\where you create the          avatarBounds          in          paint        , add together            .inflate(avatarMargin)            to the stop:          
val avatarBounds = RectFFactory.fromCircle(eye = centerAvatar, radius = avatarRadius).inflate(avatarMargin)                Calling          inflate()          on a          RectF          creates a new          RectF          object whose left, top, right and bottom edges are moved outwards by the given value. The outcome is a nice space around the avatar.
To see the margin in action, build and run the app.
          
        
Pretty... but ordinary. Adjacent, you'll spice upward the background by adding an attractive curved shape.
Adding More Neat Shapes
To enhance your custom shape, you can add some elementary decorations similar stars or circles in a partially-faded color. For this app, you'll add a more interesting ornament: A curvy shape in slope colors.
Adding a Curved Shape
Before you kickoff cartoon, take a moment to learn nigh the unlike types of curves. The Quadratic Bézier Curve and the Cubic Bézier Curve are 2 ordinarily used curves.
- A            quadratic Bézier bend            requires three points to draw: A first point, an endpoint and a handle point that pulls the bend towards it.            
             - A            cubic Bézier curve            needs four points to draw: A outset point, an end point and            ii            handle points that pull the bend towards them.            
             
Side by side, y'all'll use a quadratic Bézier curve to create an interesting background shape.
Drawing a Quadratic Bézier Curve
Beginning by creating a new function chosen          drawCurvedShape()          inside          ProfileCardPainter          with the following:
individual fun drawCurvedShape(sheet: Canvas, premises: RectF, avatarBounds: RectF) {   //1   val paint = Paint()   pigment.color = color.darkerShade()    //2   val handlePoint = PointF(bounds.left + (premises.width() * 0.25f), bounds.top)    //3   val curvePath = Path().apply {     //iv     moveTo(bounds.bottomLeft.x, bounds.bottomLeft.y)     //5     lineTo(avatarBounds.centerLeft.x, avatarBounds.centerLeft.y)     //6     arcTo(avatarBounds, -180f, 180f, false)     //vii     lineTo(bounds.bottomRight.x, bounds.bottomRight.y)     //eight     lineTo(bounds.topRight.x, premises.topRight.y)     //ix     quadTo(handlePoint.x, handlePoint.y, bounds.bottomLeft.ten, bounds.bottomLeft.y)     //x     close()   }    //xi   canvass.drawPath(curvePath, pigment) }                This diagram will aid you sympathise the code you added. Utilize it as a guide to the proper coordinates for each point you'll build to create the path:
          
        
In the previous lawmaking:
- You create a            
Paintobject and set its colour to a darker shade of the contour colour. - And so, you create a handle point at the meridian left corner of the            
RectF, shifted to the right by 25% of the width of theRectF. This is P6 in the guide image. - You create a            
Pathobject. - Then, yous motion to the bottom-left corner, P1 in the guide image.
 - You add a directly line that starts from            P1            and ends at            P2: The middle point at the border of the blackness dashed avatar bounds            
RectF. - So, starting from the current point,            P2, add an arc in the upper- half region of the avatar bounds: The arc starts from the bending            
-180degrees and sweeps by180degrees ending in P3.
You laissez passerfalseas the last parameter so you lot don't start a new sub-path for the arc. This tells Android that you want the arc on the same path. - Yous add a directly line that starts from the electric current betoken and ends at the given point, the lesser-right corner. This adds a line from P3 to P4.
 - So, you add a straight line that starts from the current signal and ends at the given betoken, the top-correct corner, adding a line from P4 to P5.
 - You add a quadratic Bézier curve that starts from the electric current point, P5, and ends at the bottom-left corner, P1, using the handle point you created in pace ii.
 - Finally, you close the path, even though it's not required this fourth dimension since you are back at the starting time indicate on the path.
 - You draw            
curvePathon the canvas past passing it todrawPath()along with thepaintobject. 
Finalizing the Bend
You're almost finished creating the bend. In          ProfileCardPainter, become to the last line in          paint()          and add the post-obit code:
//1 val curvedShapeBounds = RectFFactory.fromLTRB(     shapeBounds.left,     shapeBounds.top + shapeBounds.summit() * 0.35f,     shapeBounds.right,     shapeBounds.bottom ) //2 drawCurvedShape(canvass, curvedShapeBounds, avatarBounds)                Here, you lot:
- Create a            
RectFthat is similar to theshapeBoundsrect, except y'all've shifted its top slightly to the bottom past 35% of theshapeBounds' superlative: This is the cerise dashedRectFin the image above. - Phone call            
drawCurvedShape()and laissez passer thecanvasobject, the curved shape bounds and the avatar bounds to it. 
Build and run the app to run into the neat background curve behind the avatar:
          
        
So you're done, right? Virtually. In that location's still ane more than finishing touch y'all need to add together.
Calculation Gradient Paint
Yous've created your first beautiful, custom curved shape, but your graphic designer wants you lot to do one more than thing: Add gradient colors to your curved shape.
In that location are different types of shaders or gradients, including linear gradients, which transition through at least 2 colors in a straight line, and radial gradients, which transition through colors starting from a central point and radiating outward.
Right now, you'll create a shader, a linear gradient described past 3 colors. Each color needs a stop to specify its position on a line from 0.0 to ane.0.
Start past creating a new function called          createGradient()          within          ProfileCardPainter          with the post-obit code:
            individual fun createGradient(bounds: RectF): LinearGradient {   //ane   val colors = intArrayOf(color.darkerShade(), color, color.darkerShade())   //two   val stops = floatArrayOf(0.0f, 0.3f, 1.0f)   //iii   return LinearGradient(       premises.centerLeft.ten, bounds.centerLeft.y,       bounds.centerRight.x, bounds.centerRight.y,       colors,       stops,       Shader.TileMode.REPEAT   ) }                Here's what'due south going on in this code:
- You create a list of three colors, where the middle colour is the profile color and the first and last colors are darker shades of that profile color.
 - Then you create a list of three stops. The first is 0.0, which puts the corresponding colour in the colors list at the zero position of the gradient color. In the same manner, the center and the stops specify the positions of their respective colors in the color list.
 - Finally, you create a linear slope by passing the offset coordinates and the terminate coordinates of the gradient with the given colors and stops, and the shader TileMode to repeat the gradient in case the area which you fill up is larger than the shader you created.
 
Now become to          drawCurvedShape()          and update the          paint          object to use the new linear slope instead of a solid color.
Supersede this line:
paint.color = color.darkerShade()                With this one:
paint.shader = createGradient(bounds)                Here, yous create a new gradient and prepare it to the          paint          object.
Finally, build and run the app to see a gradient inside the background curve:
          
        
Congratulations! You've created a cute profile card with an eye-catching custom background shape and shading.
Where to Go From Hither?
You can download the completed final project using the Download Materials button at the top or bottom of the tutorial.
Wow, that was a lot of work! Merely you learned a lot, besides. In improver to taking a deep look at          Sail          and many Android Graphics APIs, you learned how to:
- Prepare your custom shape on paper before coding.
 - Use            
Pathand how to add different lines to it sequentially. - Draw a curved shape in slope colors.
 
To larn more virtually          Sheet          and Android custom views check out the post-obit links:
- Android Custom View Tutorial.
 - Making your drawing Interactive.
 - Custom Android Compound View.
 
Also, you tin can check RichPath library. It'due south an open-source library that gives you full control over your custom shapes in vector drawable format then you can manipulate and animate them easily at runtime.
Feel free to share your feedback, comments or inquire questions in the forum below. Don't stop drawing. ;]
Source: https://www.raywenderlich.com/9556022-drawing-custom-shapes-in-android
0 Response to "How to Draw a Circle in Android Studio"
Publicar un comentario