Drawing 2D objects in Android


 

In this tutorial you will learn to dynamically draw the following 2D objects: oval, rectangle, star and rectangle with rounded corner.

1. Modifying activity_main.xml file

       
         As always we will start with modifying our layout file (which is located in res\layout directory). We will be using RadioButton element to enable user to choose what object he wants to draw. We also will be using an ImageView elements to place out Drawable object into it.

activity_main.xml file:

 <RadioGroup 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"  
   android:paddingBottom="@dimen/activity_vertical_margin"  
   android:paddingLeft="@dimen/activity_horizontal_margin"  
   android:paddingRight="@dimen/activity_horizontal_margin"  
   android:paddingTop="@dimen/activity_vertical_margin"  
   android:background="#696969"  
   tools:context=".MainActivity" >  
   <TextView  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:textColor="#ffffff"  
    android:textSize="20sp"  
    android:text="@string/hint" />  
   <RadioButton   
    android:id="@+id/button1"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:textColor="#ffffff"  
    android:text="@string/oval"/>  
   <RadioButton   
    android:id="@+id/button2"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:textColor="#ffffff"  
    android:text="@string/star"/>  
   <RadioButton   
    android:id="@+id/button3"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:textColor="#ffffff"  
    android:text="@string/rectangle"/>  
   <RadioButton   
    android:id="@+id/button4"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:textColor="#ffffff"  
    android:text="@string/rrectangle"/>  
   <ImageView   
    android:id="@+id/our_imageview"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:layout_gravity="center_horizontal"/>  
 </RadioGroup>  
          In the layout file I am using five string resources, which is why we need to add five new lines to our strings.xml file (located in res\values directory): 

 <string name="oval">Oval</string>  
 <string name="star">Star</string>  
 <string name="rrectangle">Rectangle with rounded corners</string>  
 <string name="rectangle">Rectangle</string>  
 <string name="hint">Choose an object to draw:</string>  

2. Handling user input and drawing shapes

         To react to user's input we need to add onClick() event handler to all of our RadioButtons. Inside of this method we will place corresponding code that will let us draw a certain shape depending on which option had been selected.  I will give a full activity class code at the end of this article, but right now lets concentrate on the way we can draw our shapes:)
  • Oval
 ShapeDrawable d = new ShapeDrawable (new OvalShape());   
 d.setIntrinsicHeight(100);   
 d.setIntrinsicWidth(150);  
 d.getPaint().setColor(Color.rgb(0, 250, 154));   
 image.setBackgroundDrawable(d);  

      In the code above we are creating the OvalShape class object and defining all the required characteristics: object's height, width and color. After that we are placing this object into the ImgaeView element that we've added to our xml file earlier.
  • Star
 ShapeDrawable d;  
 Path p = new Path();  
 p.moveTo(48,15);   
 p.lineTo(20,100);   
 p.lineTo(90,50);   
 p.lineTo(5,50);   
 p.lineTo(70,100);   
 p.lineTo(48,15);   
 d = new ShapeDrawable (new PathShape(p, 100, 100));  
 d.setIntrinsicHeight(100);  
 d.setIntrinsicWidth(100);  
 d.getPaint().setColor(Color.rgb(255, 215, 0));  
 d.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);  
 image.setBackgroundDrawable(d);  

       To draw a star we are using Path class. The Path class encapsulates compound geometric paths consisting of straight line segments, quadratic curves, and cubic curves. To set point and move lines two public methods moveTo() and lineTo() are used.
  • Rectangle
 ShapeDrawable d = new ShapeDrawable (new RectShape());   
 d.setIntrinsicHeight(100);   
 d.setIntrinsicWidth(150);  
 d.getPaint().setColor(Color.rgb(175, 238, 238));   
 image.setBackgroundDrawable(d);  

           Here everything is very similar to drawing oval, but instead OvalShape class we are using RectShape class.  Then we set rectangle's height, width and color. 
  • Rectangle with rounded corners
  float[] outR = new float[] {6,6,6,6,6,6,6,6};   
  ShapeDrawable d = new ShapeDrawable(new RoundRectShape(outR, null, null));  
  d.setIntrinsicHeight(100);  
  d.setIntrinsicWidth(150);  
  d.getPaint().setColor(Color.rgb(240, 128, 128));  
  d.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);  
  image.setBackgroundDrawable(d);  

RoundRectShape constructor parameters:
  • outerRadii (in our case outR) - an array of 8 radius values, for the outer roundrect. The first two floats are for the top-left corner. For no rounded corners on the outer rectangle, pass null.
  • inset - a RectF that specifies the distance from the inner rect to each side of the outer rect. For no inner, pass null.
  • innerRadii - an array of 8 radius values, for the inner roundrect. The first two floats are for the top-left corner (remaining pairs correspond clockwise). For no rounded corners on the inner rectangle, pass null. If inset parameter is null, this parameter is ignored.
Full Activity class code
 package objectsexample.tuts.com;  
 import android.os.Bundle;  
 import android.app.Activity;  
 import android.content.Context;  
 import android.graphics.Color;  
 import android.graphics.Paint;  
 import android.graphics.Path;   
 import android.graphics.drawable.ShapeDrawable;  
 import android.graphics.drawable.shapes.OvalShape;  
 import android.graphics.drawable.shapes.PathShape;  
 import android.graphics.drawable.shapes.RectShape;  
 import android.graphics.drawable.shapes.RoundRectShape;   
 import android.view.View;  
 import android.view.View.OnClickListener;  
 import android.widget.ImageView;  
 import android.widget.RadioButton;  
 public class MainActivity extends Activity {  
      private RadioButton oval_button;  
      private RadioButton rectangle_button;  
      private RadioButton star_button;  
      private RadioButton rRectangle_button;  
      private ImageView image;  
      final Context context = this;   
      @Override  
      protected void onCreate(Bundle savedInstanceState) {  
           super.onCreate(savedInstanceState);  
           setContentView(R.layout.activity_main);  
           oval_button = (RadioButton) findViewById(R.id.button1);  
           rectangle_button = (RadioButton) findViewById(R.id.button3);  
           star_button = (RadioButton) findViewById(R.id.button2);  
           rRectangle_button = (RadioButton) findViewById(R.id.button4);  
           image = (ImageView) findViewById(R.id.our_imageview);  
           onClickMethod();  
      }  
      private void onClickMethod() {  
           // TODO Auto-generated method stub  
           oval_button.setOnClickListener(new OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                     ShapeDrawable d = new ShapeDrawable (new OvalShape());   
                     d.setIntrinsicHeight(100);   
                     d.setIntrinsicWidth(150);  
                     d.getPaint().setColor(Color.rgb(0, 250, 154));   
                     image.setBackgroundDrawable(d);  
                }  
           });  
           star_button.setOnClickListener(new OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                     ShapeDrawable d;  
                     Path p = new Path();  
                     p.moveTo(48,15);   
                     p.lineTo(20,100);   
                     p.lineTo(90,50);   
                     p.lineTo(5,50);   
                     p.lineTo(70,100);   
                     p.lineTo(48,15);   
                     d = new ShapeDrawable (new PathShape(p, 100, 100));  
                     d.setIntrinsicHeight(100);  
                     d.setIntrinsicWidth(100);  
                     d.getPaint().setColor(Color.rgb(255, 215, 0));  
                     d.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);  
                     image.setBackgroundDrawable(d);  
                }  
           });  
           rectangle_button.setOnClickListener(new OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                     ShapeDrawable d = new ShapeDrawable (new RectShape());   
                     d.setIntrinsicHeight(100);   
                     d.setIntrinsicWidth(150);  
                     d.getPaint().setColor(Color.rgb(175, 238, 238));   
                     image.setBackgroundDrawable(d);  
                }  
           });  
           rRectangle_button.setOnClickListener(new OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                     float[] outR = new float[] {6,6,6,6,6,6,6,6};   
                     ShapeDrawable d = new ShapeDrawable(new RoundRectShape(outR, null, null));  
                     d.setIntrinsicHeight(100);  
                     d.setIntrinsicWidth(150);  
                     d.getPaint().setColor(Color.rgb(240, 128, 128));  
                     d.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);  
                     image.setBackgroundDrawable(d);  
                }  
           });  
      }  
 }  

DEMO


Android Oval, Rectangle and Star Example
Android Oval, Rectangle and Star Example

Source code

References: