Draw Circle Using Path in Android

Overview

Let's take a await at building a custom view that allows the user to paint on the screen past pressing downwardly their finger. This volition illustrate how to build custom components, how to draw shapes and paths on a view and too how to handle user touch interactions.

Creating our Custom View

Create a simple form for cartoon that extends View called SimpleDrawingView:

                      public            grade            SimpleDrawingView            extends            View            {            public            SimpleDrawingView            (            Context            context            ,            AttributeSet            attrs            )            {            super            (            context            ,            attrs            );            }            }                  

Add this to the XML layout for action so our custom view is embedded inside:

                      <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.example.simpledrawapp.SimpleDrawingView            android:id=            "@+id/simpleDrawingView1"            android:layout_width=            "wrap_content"            android:layout_height=            "wrap_content"            android:layout_alignParentBottom=            "true"            android:layout_alignParentLeft=            "true"            android:layout_alignParentRight=            "true"            android:layout_alignParentTop=            "true"            />            </RelativeLayout>                  

Simple Drawing with Canvass

Allow's try cartoon a couple of circles on screen. This requires the states to ascertain a Paint object which controls the styling and color of what is drawn. Let'due south start past preparing the paint:

                      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 paint with color and stroke styles            private            void            setupPaint            ()            {            drawPaint            =            new            Paint            ();            drawPaint            .            setColor            (            paintColor            );            drawPaint            .            setAntiAlias            (            true            );            drawPaint            .            setStrokeWidth            (            5            );            drawPaint            .            setStyle            (            Pigment            .            Fashion            .            STROKE            );            drawPaint            .            setStrokeJoin            (            Paint            .            Join            .            ROUND            );            drawPaint            .            setStrokeCap            (            Paint            .            Cap            .            Circular            );            }            }                  

Now that nosotros have the paint setup to have a black color and configured a particular stroke style, let's try to draw a few circles with dissimilar colors. All drawing that happens in a view should take identify 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 three circles            @Override            protected            void            onDraw            (            Canvas            canvas            )            {            canvas            .            drawCircle            (            50            ,            50            ,            20            ,            drawPaint            );            drawPaint            .            setColor            (            Colour            .            GREEN            );            canvas            .            drawCircle            (            fifty            ,            150            ,            twenty            ,            drawPaint            );            drawPaint            .            setColor            (            Color            .            BLUE            );            canvass            .            drawCircle            (            50            ,            250            ,            xx            ,            drawPaint            );            }            }                  

Observe that onDraw passes us a canvas object which we use to draw leveraging the Pigment nosotros divers earlier. The drawCircle method accepts the x, y and radius of the circle in addition to the paint. This renders the following:

Circle

Handling Touch Interactions

Suppose now we wanted to draw a circle every time the user touches down on the drawing view. This would require u.s. to go on runway of an assortment of points for our circles so append a point for each onTouch outcome triggered:

                      public            form            SimpleDrawingView            extends            View            {            // setup initial color            individual            final            int            paintColor            =            Colour            .            Blackness            ;            // defines pigment and sheet            individual            Paint            drawPaint            ;            // Shop circles to describe each time the user touches down            individual            List            <            Indicate            >            circlePoints            ;            public            SimpleDrawingView            (            Context            context            ,            AttributeSet            attrs            )            {            super            (            context            ,            attrs            );            setupPaint            ();            // same equally before            circlePoints            =            new            ArrayList            <            Point            >();            }            // Draw each circle onto the view            @Override            protected            void            onDraw            (            Sheet            canvas            )            {            for            (            Point            p            :            circlePoints            )            {            sheet            .            drawCircle            (            p            .            x            ,            p            .            y            ,            5            ,            drawPaint            );            }            }            // Append new circle each time user presses on screen            @Override            public            boolean            onTouchEvent            (            MotionEvent            effect            )            {            float            touchX            =            consequence            .            getX            ();            float            touchY            =            consequence            .            getY            ();            circlePoints            .            add together            (            new            Point            (            Math            .            round            (            touchX            ),            Math            .            circular            (            touchY            )));            // indicate view should be redrawn            postInvalidate            ();            render            true            ;            }            private            void            setupPaint            ()            {            // same equally earlier            drawPaint            .            setStyle            (            Paint            .            Style            .            Fill            );            // change to make full            // ...            }            }                  

with this, a blackness circumvolve is drawn each time nosotros press down:

Circle 2

Drawing with Paths

And so far we have explored the onDraw method of a view and we were able to depict circles onto the view based on impact interactions with the view. Adjacent, allow's meliorate our drawing application by 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 even other shapes. Offset, allow's add together a Path variable to track our cartoon:

                      public            class            SimpleDrawingView            extends            View            {            // ...            individual            Path            path            =            new            Path            ();            // ...            }                  

Next, allow's suspend points to the path every bit the user touches the screen. When the user presses down, let's start a path and then when they drag let's connect the points together. To exercise this, we need alter the onTouchEvent to append these points to our Path object:

                      public            course            SimpleDrawingView            extends            View            {            private            Path            path            =            new            Path            ();            // Become 10 and y and suspend them to the path            public            boolean            onTouchEvent            (            MotionEvent            outcome            )            {            bladder            pointX            =            event            .            getX            ();            float            pointY            =            upshot            .            getY            ();            // Checks for the effect that occurs            switch            (            event            .            getAction            ())            {            example            MotionEvent            .            ACTION_DOWN            :            // Starts a new line in the path            path            .            moveTo            (            pointX            ,            pointY            );            interruption            ;            case            MotionEvent            .            ACTION_MOVE            :            // Draws line between last point and this point            path            .            lineTo            (            pointX            ,            pointY            );            intermission            ;            default            :            return            false            ;            }            postInvalidate            ();            // Signal view should be redrawn            return            true            ;            // Indicate we've consumed the affect            }            // ...            }                  

and and then let'southward alter the onDraw to remove the circles and instead to render the lines we have plotted in our path:

                      public            class            SimpleDrawingView            extends            View            {            // ... onTouchEvent ...            // Draws the path created during the affect events            @Override            protected            void            onDraw            (            Canvas            canvas            )            {            canvas            .            drawPath            (            path            ,            drawPaint            );            }            private            void            setupPaint            ()            {            // same as earlier            drawPaint            .            setStyle            (            Paint            .            Style            .            STROKE            );            // modify back to stroke            // ...            }            }                  

and with that, nosotros have a very basic painting app that looks like:

Circle 3

Efficient Drawing with Bitmap Cache

When drawing onto a canvas, you lot tin oftentimes significantly improve return times past caching the image into a bitmap as outlined in this stackoverflow postal service.

                      Bitmap            mField            =            nix            ;            public            void            init            ()            {            mField            =            new            Bitmap            (...            dimensions            ...);            Canvas            c            =            new            Canvas            (            mField            );            c            .            drawRect            (...);            ...            }            public            void            onDraw            (            Canvass            c            )            {            c            .            drawBitmap            (            mField            );            }                  

This is a common design for improving drawing operation.

Reference for SimpleDrawingView

The full source code for our SimpleDrawingView:

                      package            com            .            codepath            .            instance            .            simpledrawapp            ;            import            android.content.Context            ;            import            android.graphics.Sail            ;            import            android.graphics.Color            ;            import            android.graphics.Pigment            ;            import            android.graphics.Path            ;            import            android.util.AttributeSet            ;            import            android.view.MotionEvent            ;            import            android.view.View            ;            public            class            SimpleDrawingView            extends            View            {            // setup initial color            individual            final            int            paintColor            =            Color            .            BLACK            ;            // defines paint and canvas            individual            Paint            drawPaint            ;            // stores side by side circle            private            Path            path            =            new            Path            ();            public            SimpleDrawingView            (            Context            context            ,            AttributeSet            attrs            )            {            super            (            context            ,            attrs            );            setFocusable            (            truthful            );            setFocusableInTouchMode            (            true            );            setupPaint            ();            }            private            void            setupPaint            ()            {            // Setup pigment with color and stroke styles            drawPaint            =            new            Paint            ();            drawPaint            .            setColor            (            paintColor            );            drawPaint            .            setAntiAlias            (            truthful            );            drawPaint            .            setStrokeWidth            (            five            );            drawPaint            .            setStyle            (            Pigment            .            Style            .            STROKE            );            drawPaint            .            setStrokeJoin            (            Paint            .            Bring together            .            Circular            );            drawPaint            .            setStrokeCap            (            Paint            .            Cap            .            ROUND            );            }            @Override            protected            void            onDraw            (            Canvass            canvas            )            {            canvas            .            drawPath            (            path            ,            drawPaint            );            }            @Override            public            boolean            onTouchEvent            (            MotionEvent            event            )            {            bladder            pointX            =            effect            .            getX            ();            bladder            pointY            =            event            .            getY            ();            // Checks for the event that occurs            switch            (            event            .            getAction            ())            {            case            MotionEvent            .            ACTION_DOWN            :            path            .            moveTo            (            pointX            ,            pointY            );            return            true            ;            case            MotionEvent            .            ACTION_MOVE            :            path            .            lineTo            (            pointX            ,            pointY            );            break            ;            default            :            return            simulated            ;            }            // Strength a view to draw again            postInvalidate            ();            return            true            ;            }            }                  

Drawing with Density Independent Pixels

When drawing or animating, you oft want to draw using density independent pixels in order to be robust to different device sizes and densities. You may besides want to determine the device pinnacle or width in guild to draw intelligently. Copy this DeviceDimensionsHelper.java utility grade to DeviceDimensionsHelper.java in your project and utilise anywhere that yous take a context to decide screen dimensions or practise translations between dp and px:

                      // Go height or width of screen            int            screenHeight            =            DeviceDimensionsHelper            .            getDisplayHeight            (            this            );            int            screenWidth            =            DeviceDimensionsHelper            .            getDisplayWidth            (            this            );            // Convert dp to pixels            float            px            =            DeviceDimensionsHelper            .            convertDpToPixel            (            25            f            ,            this            );            // Convert pixels to dp            bladder            dp            =            DeviceDimensionsHelper            .            convertPixelsToDp            (            25            f            ,            this            );                  

You can then use this to practise smarter drawing for more responsive custom views.

riostorcer75.blogspot.com

Source: https://guides.codepath.com/android/Basic-Painting-with-Views

0 Response to "Draw Circle Using Path in Android"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel