Android Tutorial - 2D Graphics : example 1

 Arcs

package app.test;


import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    private static class SampleView extends View {
        private Paint[] mPaints;
        private Paint mFramePaint;
        private boolean[] mUseCenters;
        private RectF[] mOvals;
        private RectF mBigOval;
        private float mStart;
        private float mSweep;
        private int mBigIndex;

        private static final float SWEEP_INC = 2;
        private static final float START_INC = 15;

        public SampleView(Context context) {
            super(context);

            mPaints = new Paint[4];
            mUseCenters = new boolean[4];
            mOvals = new RectF[4];

            mPaints[0] = new Paint();
            mPaints[0].setAntiAlias(true);
            mPaints[0].setStyle(Paint.Style.FILL);
            mPaints[0].setColor(0x88FF0000);
            mUseCenters[0] = false;

            mPaints[1] = new Paint(mPaints[0]);
            mPaints[1].setColor(0x8800FF00);
            mUseCenters[1] = true;

            mPaints[2] = new Paint(mPaints[0]);
            mPaints[2].setStyle(Paint.Style.STROKE);
            mPaints[2].setStrokeWidth(4);
            mPaints[2].setColor(0x880000FF);
            mUseCenters[2] = false;

            mPaints[3] = new Paint(mPaints[2]);
            mPaints[3].setColor(0x88888888);
            mUseCenters[3] = true;

            mBigOval = new RectF(40, 10, 280, 250);

            mOvals[0] = new RectF( 10, 270,  70, 330);
            mOvals[1] = new RectF( 90, 270, 150, 330);
            mOvals[2] = new RectF(170, 270, 230, 330);
            mOvals[3] = new RectF(250, 270, 310, 330);

            mFramePaint = new Paint();
            mFramePaint.setAntiAlias(true);
            mFramePaint.setStyle(Paint.Style.STROKE);
            mFramePaint.setStrokeWidth(0);
        }

        private void drawArcs(Canvas canvas, RectF oval, boolean useCenter,
                              Paint paint) {
            canvas.drawRect(oval, mFramePaint);
            canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
        }

        @Override protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);

            drawArcs(canvas, mBigOval, mUseCenters[mBigIndex],
                     mPaints[mBigIndex]);

            for (int i = 0; i < 4; i++) {
                drawArcs(canvas, mOvals[i], mUseCenters[i], mPaints[i]);
            }

            mSweep += SWEEP_INC;
            if (mSweep > 360) {
                mSweep -= 360;
                mStart += START_INC;
                if (mStart >= 360) {
                    mStart -= 360;
                }
                mBigIndex = (mBigIndex + 1) % mOvals.length;
            }
            invalidate();
        }
    }
}

class GraphicsActivity extends Activity {
    // set to true to test Picture
    private static final boolean TEST_PICTURE = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void setContentView(View view) {
        if (TEST_PICTURE) {
            ViewGroup vg = new PictureLayout(this);
            vg.addView(view);
            view = vg;
        }

        super.setContentView(view);
    }
}

class PictureLayout extends ViewGroup {
    private final Picture mPicture = new Picture();

    public PictureLayout(Context context) {
        super(context);
    }

    public PictureLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void addView(View child) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child);
    }

    @Override
    public void addView(View child, int index) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child, index);
    }

    @Override
    public void addView(View child, LayoutParams params) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child, params);
    }

    @Override
    public void addView(View child, int index, LayoutParams params) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child, index, params);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int count = getChildCount();

        int maxHeight = 0;
        int maxWidth = 0;

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
            }
        }

        maxWidth += getPaddingLeft() + getPaddingRight();
        maxHeight += getPaddingTop() + getPaddingBottom();

        Drawable drawable = getBackground();
        if (drawable != null) {
            maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
            maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
        }

        setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
                resolveSize(maxHeight, heightMeasureSpec));
    }

    private void drawPict(Canvas canvas, int x, int y, int w, int h,
                          float sx, float sy) {
        canvas.save();
        canvas.translate(x, y);
        canvas.clipRect(0, 0, w, h);
        canvas.scale(0.5f, 0.5f);
        canvas.scale(sx, sy, w, h);
        canvas.drawPicture(mPicture);
        canvas.restore();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
        mPicture.endRecording();

        int x = getWidth()/2;
        int y = getHeight()/2;

        if (false) {
            canvas.drawPicture(mPicture);
        } else {
            drawPict(canvas, 0, 0, x, y,  1,  1);
            drawPict(canvas, x, 0, x, y, -1,  1);
            drawPict(canvas, 0, y, x, y,  1, -1);
            drawPict(canvas, x, y, x, y, -1, -1);
        }
    }

    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        location[0] = getLeft();
        location[1] = getTop();
        dirty.set(0, 0, getWidth(), getHeight());
        return getParent();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = super.getChildCount();

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final int childLeft = getPaddingLeft();
                final int childTop = getPaddingTop();
                child.layout(childLeft, childTop,
                        childLeft + child.getMeasuredWidth(),
                        childTop + child.getMeasuredHeight());

            }
        }
    }
}

Clipping Demo

package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private Paint mPaint;
    private Path mPath;

    public SampleView(Context context) {
      super(context);
      setFocusable(true);

      mPaint = new Paint();
      mPaint.setAntiAlias(true);
      mPaint.setStrokeWidth(6);
      mPaint.setTextSize(16);
      mPaint.setTextAlign(Paint.Align.RIGHT);

      mPath = new Path();
    }

    private void drawScene(Canvas canvas) {
      canvas.clipRect(0, 0, 100, 100);

      canvas.drawColor(Color.WHITE);

      mPaint.setColor(Color.RED);
      canvas.drawLine(0, 0, 100, 100, mPaint);

      mPaint.setColor(Color.GREEN);
      canvas.drawCircle(30, 70, 30, mPaint);

      mPaint.setColor(Color.BLUE);
      canvas.drawText("Clipping", 100, 30, mPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(Color.GRAY);

      canvas.save();
      canvas.translate(10, 10);
      drawScene(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(160, 10);
      canvas.clipRect(10, 10, 90, 90);
      canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
      drawScene(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(10, 160);
      mPath.reset();
      canvas.clipPath(mPath); // makes the clip empty
      mPath.addCircle(50, 50, 50, Path.Direction.CCW);
      canvas.clipPath(mPath, Region.Op.REPLACE);
      drawScene(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(160, 160);
      canvas.clipRect(0, 0, 60, 60);
      canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);
      drawScene(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(10, 310);
      canvas.clipRect(0, 0, 60, 60);
      canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);
      drawScene(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(160, 310);
      canvas.clipRect(0, 0, 60, 60);
      canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE);
      drawScene(canvas);
      canvas.restore();
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

Draw animated gif

package app.test;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private Bitmap mBitmap;
    private Bitmap mBitmap2;
    private Bitmap mBitmap3;
    private Bitmap mBitmap4;
    private Drawable mDrawable;

    private Movie mMovie;
    private long mMovieStart;

    // Set to false to use decodeByteArray
    private static final boolean DECODE_STREAM = true;

    private static byte[] streamToBytes(InputStream is) {
      ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
      byte[] buffer = new byte[1024];
      int len;
      try {
        while ((len = is.read(buffer)) >= 0) {
          os.write(buffer, 0, len);
        }
      } catch (java.io.IOException e) {
      }
      return os.toByteArray();
    }

    public SampleView(Context context) {
      super(context);
      setFocusable(true);

      java.io.InputStream is;
      is = context.getResources().openRawResource(R.drawable.icon);

      BitmapFactory.Options opts = new BitmapFactory.Options();
      Bitmap bm;

      opts.inJustDecodeBounds = true;
      bm = BitmapFactory.decodeStream(is, null, opts);

      // now opts.outWidth and opts.outHeight are the dimension of the
      // bitmap, even though bm is null

      opts.inJustDecodeBounds = false; // this will request the bm
      opts.inSampleSize = 4; // scaled down by 4
      bm = BitmapFactory.decodeStream(is, null, opts);

      mBitmap = bm;

      // decode an image with transparency
      is = context.getResources().openRawResource(R.drawable.icon);
      mBitmap2 = BitmapFactory.decodeStream(is);

      // create a deep copy of it using getPixels() into different configs
      int w = mBitmap2.getWidth();
      int h = mBitmap2.getHeight();
      int[] pixels = new int[w * h];
      mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
      mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
          Bitmap.Config.ARGB_8888);
      mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
          Bitmap.Config.ARGB_4444);

      mDrawable = context.getResources().getDrawable(R.drawable.icon);
      mDrawable.setBounds(150, 20, 300, 100);

      is = context.getResources().openRawResource(R.drawable.animated_gif);

      if (DECODE_STREAM) {
        mMovie = Movie.decodeStream(is);
      } else {
        byte[] array = streamToBytes(is);
        mMovie = Movie.decodeByteArray(array, 0, array.length);
      }
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(0xFFCCCCCC);

      Paint p = new Paint();
      p.setAntiAlias(true);

      canvas.drawBitmap(mBitmap, 10, 10, null);
      canvas.drawBitmap(mBitmap2, 10, 170, null);
      canvas.drawBitmap(mBitmap3, 110, 170, null);
      canvas.drawBitmap(mBitmap4, 210, 170, null);

      mDrawable.draw(canvas);

      long now = android.os.SystemClock.uptimeMillis();
      if (mMovieStart == 0) { // first time
        mMovieStart = now;
      }
      if (mMovie != null) {
        int dur = mMovie.duration();
        if (dur == 0) {
          dur = 1000;
        }
        int relTime = (int) ((now - mMovieStart) % dur);
        mMovie.setTime(relTime);
        mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
            - mMovie.height());
        invalidate();
      }
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

Paint

Paint.ANTI_ALIAS_FLAG

  


package app.Test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.os.Bundle;
import android.view.View;

public class appTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new GraphicsView(this));
  }
  static public class GraphicsView extends View {
    private static final String QUOTE = "This is a test. This is a demo.";
    private Path circle;
    private Paint cPaint;
    private Paint tPaint;

    public GraphicsView(Context context) {
      super(context);

      int color = Color.BLUE; 

      circle = new Path();
      circle.addCircle(150, 150, 100, Direction.CW);

      cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      cPaint.setStyle(Paint.Style.STROKE);
      cPaint.setColor(Color.LTGRAY);
      cPaint.setStrokeWidth(3);

      setBackgroundResource(R.drawable.icon);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawPath(circle, cPaint);
    }
  }
}


//main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="@drawable/icon">
   <org.example.graphics.Graphics.GraphicsView
      android:id="@+id/graphics"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" />
</LinearLayout>


//strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Graphics</string>

</resources>


//colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="mycolor">#7fff00ff</color> 
</resources>

Paint.Style.STROKE

  

package app.Test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.os.Bundle;
import android.view.View;

public class appTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new GraphicsView(this));
  }
  static public class GraphicsView extends View {
    private static final String QUOTE = "This is a test. This is a demo.";
    private Path circle;
    private Paint cPaint;
    private Paint tPaint;

    public GraphicsView(Context context) {
      super(context);

      int color = Color.BLUE; 

      circle = new Path();
      circle.addCircle(150, 150, 100, Direction.CW);

      cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      cPaint.setStyle(Paint.Style.STROKE);
      cPaint.setColor(Color.LTGRAY);
      cPaint.setStrokeWidth(3);

      setBackgroundResource(R.drawable.icon);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawPath(circle, cPaint);
    }
  }
}


//main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="@drawable/icon">
   <org.example.graphics.Graphics.GraphicsView
      android:id="@+id/graphics"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" />
</LinearLayout>


//strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Graphics</string>

</resources>


//colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="mycolor">#7fff00ff</color> 
</resources>
Finger Paint
package app.test;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.EmbossMaskFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity implements
    ColorPickerDialog.OnColorChangedListener {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MyView(this));

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0xFFFF0000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

    mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);

    mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
  }

  private Paint mPaint;
  private MaskFilter mEmboss;
  private MaskFilter mBlur;

  public void colorChanged(int color) {
    mPaint.setColor(color);
  }

  public class MyView extends View {

    private static final float MINP = 0.25f;
    private static final float MAXP = 0.75f;

    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;

    public MyView(Context c) {
      super(c);

      mPath = new Path();
      mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      super.onSizeChanged(w, h, oldw, oldh);
      mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
      mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(0xFFAAAAAA);

      canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

      canvas.drawPath(mPath, mPaint);
    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touch_start(float x, float y) {
      mPath.reset();
      mPath.moveTo(x, y);
      mX = x;
      mY = y;
    }

    private void touch_move(float x, float y) {
      float dx = Math.abs(x - mX);
      float dy = Math.abs(y - mY);
      if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        mY = y;
      }
    }

    private void touch_up() {
      mPath.lineTo(mX, mY);
      // commit the path to our offscreen
      mCanvas.drawPath(mPath, mPaint);
      // kill this so we don't double draw
      mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      float x = event.getX();
      float y = event.getY();

      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        touch_start(x, y);
        invalidate();
        break;
      case MotionEvent.ACTION_MOVE:
        touch_move(x, y);
        invalidate();
        break;
      case MotionEvent.ACTION_UP:
        touch_up();
        invalidate();
        break;
      }
      return true;
    }
  }

  private static final int COLOR_MENU_ID = Menu.FIRST;
  private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
  private static final int BLUR_MENU_ID = Menu.FIRST + 2;
  private static final int ERASE_MENU_ID = Menu.FIRST + 3;
  private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
    menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
    menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
    menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
    menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');

    /****
     * Is this the mechanism to extend with filter effects? Intent intent =
     * new Intent(null, getIntent().getData());
     * intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
     * menu.addIntentOptions( Menu.ALTERNATIVE, 0, new ComponentName(this,
     * NotesList.class), null, intent, 0, null);
     *****/
    return true;
  }

  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    mPaint.setXfermode(null);
    mPaint.setAlpha(0xFF);

    switch (item.getItemId()) {
    case COLOR_MENU_ID:
      new ColorPickerDialog(this, this, mPaint.getColor()).show();
      return true;
    case EMBOSS_MENU_ID:
      if (mPaint.getMaskFilter() != mEmboss) {
        mPaint.setMaskFilter(mEmboss);
      } else {
        mPaint.setMaskFilter(null);
      }
      return true;
    case BLUR_MENU_ID:
      if (mPaint.getMaskFilter() != mBlur) {
        mPaint.setMaskFilter(mBlur);
      } else {
        mPaint.setMaskFilter(null);
      }
      return true;
    case ERASE_MENU_ID:
      mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
      return true;
    case SRCATOP_MENU_ID:
      mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
      mPaint.setAlpha(0x80);
      return true;
    }
    return super.onOptionsItemSelected(item);
  }
}

class ColorPickerDialog extends Dialog {

  public interface OnColorChangedListener {
    void colorChanged(int color);
  }

  private OnColorChangedListener mListener;
  private int mInitialColor;

  private static class ColorPickerView extends View {
    private Paint mPaint;
    private Paint mCenterPaint;
    private final int[] mColors;
    private OnColorChangedListener mListener;

    ColorPickerView(Context c, OnColorChangedListener l, int color) {
      super(c);
      mListener = l;
      mColors = new int[] { 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,
          0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000 };
      Shader s = new SweepGradient(0, 0, mColors, null);

      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mPaint.setShader(s);
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setStrokeWidth(32);

      mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mCenterPaint.setColor(color);
      mCenterPaint.setStrokeWidth(5);
    }

    private boolean mTrackingCenter;
    private boolean mHighlightCenter;

    @Override
    protected void onDraw(Canvas canvas) {
      float r = CENTER_X - mPaint.getStrokeWidth() * 0.5f;

      canvas.translate(CENTER_X, CENTER_X);

      canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
      canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);

      if (mTrackingCenter) {
        int c = mCenterPaint.getColor();
        mCenterPaint.setStyle(Paint.Style.STROKE);

        if (mHighlightCenter) {
          mCenterPaint.setAlpha(0xFF);
        } else {
          mCenterPaint.setAlpha(0x80);
        }
        canvas.drawCircle(0, 0,
            CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
            mCenterPaint);

        mCenterPaint.setStyle(Paint.Style.FILL);
        mCenterPaint.setColor(c);
      }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      setMeasuredDimension(CENTER_X * 2, CENTER_Y * 2);
    }

    private static final int CENTER_X = 100;
    private static final int CENTER_Y = 100;
    private static final int CENTER_RADIUS = 32;

    private int floatToByte(float x) {
      int n = java.lang.Math.round(x);
      return n;
    }

    private int pinToByte(int n) {
      if (n < 0) {
        n = 0;
      } else if (n > 255) {
        n = 255;
      }
      return n;
    }

    private int ave(int s, int d, float p) {
      return s + java.lang.Math.round(p * (d - s));
    }

    private int interpColor(int colors[], float unit) {
      if (unit <= 0) {
        return colors[0];
      }
      if (unit >= 1) {
        return colors[colors.length - 1];
      }

      float p = unit * (colors.length - 1);
      int i = (int) p;
      p -= i;

      // now p is just the fractional part [0...1) and i is the index
      int c0 = colors[i];
      int c1 = colors[i + 1];
      int a = ave(Color.alpha(c0), Color.alpha(c1), p);
      int r = ave(Color.red(c0), Color.red(c1), p);
      int g = ave(Color.green(c0), Color.green(c1), p);
      int b = ave(Color.blue(c0), Color.blue(c1), p);

      return Color.argb(a, r, g, b);
    }

    private int rotateColor(int color, float rad) {
      float deg = rad * 180 / 3.1415927f;
      int r = Color.red(color);
      int g = Color.green(color);
      int b = Color.blue(color);

      ColorMatrix cm = new ColorMatrix();
      ColorMatrix tmp = new ColorMatrix();

      cm.setRGB2YUV();
      tmp.setRotate(0, deg);
      cm.postConcat(tmp);
      tmp.setYUV2RGB();
      cm.postConcat(tmp);

      final float[] a = cm.getArray();

      int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
      int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
      int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);

      return Color.argb(Color.alpha(color), pinToByte(ir), pinToByte(ig),
          pinToByte(ib));
    }

    private static final float PI = 3.1415926f;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      float x = event.getX() - CENTER_X;
      float y = event.getY() - CENTER_Y;
      boolean inCenter = java.lang.Math.sqrt(x * x + y * y) <= CENTER_RADIUS;

      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mTrackingCenter = inCenter;
        if (inCenter) {
          mHighlightCenter = true;
          invalidate();
          break;
        }
      case MotionEvent.ACTION_MOVE:
        if (mTrackingCenter) {
          if (mHighlightCenter != inCenter) {
            mHighlightCenter = inCenter;
            invalidate();
          }
        } else {
          float angle = (float) java.lang.Math.atan2(y, x);
          // need to turn angle [-PI ... PI] into unit [0....1]
          float unit = angle / (2 * PI);
          if (unit < 0) {
            unit += 1;
          }
          mCenterPaint.setColor(interpColor(mColors, unit));
          invalidate();
        }
        break;
      case MotionEvent.ACTION_UP:
        if (mTrackingCenter) {
          if (inCenter) {
            mListener.colorChanged(mCenterPaint.getColor());
          }
          mTrackingCenter = false; // so we draw w/o halo
          invalidate();
        }
        break;
      }
      return true;
    }
  }

  public ColorPickerDialog(Context context, OnColorChangedListener listener,
      int initialColor) {
    super(context);

    mListener = listener;
    mInitialColor = initialColor;
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    OnColorChangedListener l = new OnColorChangedListener() {
      public void colorChanged(int color) {
        mListener.colorChanged(color);
        dismiss();
      }
    };

    setContentView(new ColorPickerView(getContext(), l, mInitialColor));
    setTitle("Pick a Color");
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

Finger Paint View

   
//package com.aflyroc.doodle.view;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class FingerPaintView extends View {
  Path path;
  Bitmap bitmapBuff;
  Paint paint;
  Paint pen;
  Canvas canvas;
  Bitmap originBitmap;
  Bitmap pureBitmp;
  private float scaleWidth;
  private float scaleHeight;
  private float mX,mY;
  private static float TOUCH_TOLERANCE = 4;
  private Canvas printCanvas;
  Bitmap printBitmapBuff;
  private List<Path> pathList;
  int i = 0;

  public FingerPaintView(Context context, AttributeSet attrs) {
    super(context, attrs);
    loadBitmap(context);
    Log.i("Context context, AttributeSet attrs", "11");
  }

  public FingerPaintView(Context context) {
    super(context);
    loadBitmap(context);
    Log.i("Context context", "222");
  }

  public void loadBitmap(Context context) {
    
    pathList = new ArrayList<Path>();
    path = new Path();
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setDither(true);
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(1.6f);
    

    InputStream stream = null;//getResources().openRawResource(drawable.precheck);

    originBitmap = BitmapFactory.decodeStream(stream);

    int width = originBitmap.getWidth();

    int height = originBitmap.getHeight();
    
    DisplayMetrics metrics = context.getApplicationContext().getResources().getDisplayMetrics(); 

    int newWidth = metrics.widthPixels;
    
    int newHeight = metrics.heightPixels;

    // 
    scaleWidth = ((float) newWidth / width);
    
    scaleHeight = ((float) newHeight / height);

    Matrix matrix = new Matrix();

    matrix.postScale(scaleWidth, scaleHeight);

    pureBitmp = Bitmap.createBitmap(originBitmap, 0, 0, width, height,matrix, true);

    bitmapBuff = Bitmap.createBitmap(pureBitmp.getWidth(),pureBitmp.getHeight(), Bitmap.Config.ARGB_8888);
    
    canvas = new Canvas(bitmapBuff);

    canvas.drawBitmap(pureBitmp, 0, 0, paint);

  }

  public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      touchStart(x, y);
      invalidate();
      break;
    case MotionEvent.ACTION_MOVE:
      touchMove(x, y);
      invalidate();
      break;
    case MotionEvent.ACTION_UP:
      touchUp(x, y);
      invalidate();
      break;
    }
    return true;
  }

  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 

    canvas.drawBitmap(bitmapBuff, 0, 0, paint);
    // 
    canvas.drawPath(path, paint);

  }
  private void touchStart(float x, float y)
  {
    path.reset();
    path.moveTo(x, y);
    mX = x;
    mY=y;
    
  }
  private void touchMove(float x,float y)
  {
    float dx = Math.abs(x-mX);
    float dy = Math.abs(y-mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
      path.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
            
        }
  }
  private void touchUp(float x,float y)
  {

    pathList.add(new Path(path));
    
    canvas.drawPath(path,paint);
    
    path.reset();
  }
  public void createPrintCanvas()
  {

    Bitmap printBitmap = Bitmap.createBitmap(originBitmap);
    
    printBitmapBuff = Bitmap.createBitmap(printBitmap.getWidth(),printBitmap.getHeight(), Bitmap.Config.ARGB_8888);
    
    Matrix matrix = new Matrix();

    matrix.postScale(1/scaleWidth, 1/scaleHeight);
    
    printCanvas = new Canvas(printBitmapBuff);
    
    printCanvas.drawBitmap(printBitmap, 0, 0, paint);
    
    for(int i=0;i<pathList.size();i++)
    {
      Path tempPath = new Path(pathList.get(i));
      
      tempPath.transform(matrix);
      
      printCanvas.drawPath(tempPath, paint);
      
      Log.d("path", tempPath.toString());
      
    }
    
    printCanvas.save();

  }

  public float getScaleWidth() {
    return scaleWidth;
  }

  public float getScaleHeight() {
    return scaleHeight;
  }

}

Point

Draw a point

 
package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStrokeWidth(100);
    canvas.drawPoint(199, 201, paint);

  }
}

Draw Points

package app.test;

import java.io.ByteArrayOutputStream;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    private static class SampleView extends View {
        private Paint   mPaint = new Paint();
        private float[] mPts;

        private static final float SIZE = 300;
        private static final int SEGS = 32;
        private static final int X = 0;
        private static final int Y = 1;

        private void buildPoints() {
            final int ptCount = (SEGS + 1) * 2;
            mPts = new float[ptCount * 2];

            float value = 0;
            final float delta = SIZE / SEGS;
            for (int i = 0; i <= SEGS; i++) {
                mPts[i*4 + X] = SIZE - value;
                mPts[i*4 + Y] = 0;
                mPts[i*4 + X + 2] = 0;
                mPts[i*4 + Y + 2] = value;
                value += delta;
            }
        }

        public SampleView(Context context) {
            super(context);

            buildPoints();
        }

        @Override protected void onDraw(Canvas canvas) {
            Paint paint = mPaint;

            canvas.translate(10, 10);

            canvas.drawColor(Color.WHITE);

            paint.setColor(Color.RED);
            paint.setStrokeWidth(0);
            canvas.drawLines(mPts, paint);

            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(3);
            canvas.drawPoints(mPts, paint);
        }
    }
}


class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

PorterDuffXfermode

new PorterDuffXfermode(PorterDuff.Mode.SRC)

package app.test;


import java.io.InputStream;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    private static class SampleView extends View {
        private Bitmap mBitmap;
        private Bitmap mBitmap2;
        private Bitmap mBitmap3;
        private Shader mShader;

        private static void drawIntoBitmap(Bitmap bm) {
            float x = bm.getWidth();
            float y = bm.getHeight();
            Canvas c = new Canvas(bm);
            Paint p = new Paint();
            p.setAntiAlias(true);

            p.setAlpha(0x80);
            c.drawCircle(x/2, y/2, x/2, p);

            p.setAlpha(0x30);
            p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
            p.setTextSize(60);
            p.setTextAlign(Paint.Align.CENTER);
            Paint.FontMetrics fm = p.getFontMetrics();
            c.drawText("Alpha", x/2, (y-fm.ascent)/2, p);
        }

        public SampleView(Context context) {
            super(context);
            setFocusable(true);

            InputStream is = context.getResources().openRawResource(R.drawable.icon);
            mBitmap = BitmapFactory.decodeStream(is);
            mBitmap2 = mBitmap.extractAlpha();
            mBitmap3 = Bitmap.createBitmap(200, 200, Bitmap.Config.ALPHA_8);
            drawIntoBitmap(mBitmap3);

            mShader = new LinearGradient(0, 0, 100, 70, new int[] {
                                         Color.RED, Color.GREEN, Color.BLUE },
                                         null, Shader.TileMode.MIRROR);
        }

        @Override protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);

            Paint p = new Paint();
            float y = 10;

            p.setColor(Color.RED);
            canvas.drawBitmap(mBitmap, 10, y, p);
            y += mBitmap.getHeight() + 10;
            canvas.drawBitmap(mBitmap2, 10, y, p);
            y += mBitmap2.getHeight() + 10;
            p.setShader(mShader);
            canvas.drawBitmap(mBitmap3, 10, y, p);
        }
    }
}
class GraphicsActivity extends Activity {
    // set to true to test Picture
    private static final boolean TEST_PICTURE = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void setContentView(View view) {
        if (TEST_PICTURE) {
            ViewGroup vg = new PictureLayout(this);
            vg.addView(view);
            view = vg;
        }

        super.setContentView(view);
    }
}
class PictureLayout extends ViewGroup {
    private final Picture mPicture = new Picture();

    public PictureLayout(Context context) {
        super(context);
    }

    public PictureLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void addView(View child) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child);
    }

    @Override
    public void addView(View child, int index) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child, index);
    }

    @Override
    public void addView(View child, LayoutParams params) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child, params);
    }

    @Override
    public void addView(View child, int index, LayoutParams params) {
        if (getChildCount() > 1) {
            throw new IllegalStateException("PictureLayout can host only one direct child");
        }

        super.addView(child, index, params);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int count = getChildCount();

        int maxHeight = 0;
        int maxWidth = 0;

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
            }
        }

        maxWidth += getPaddingLeft() + getPaddingRight();
        maxHeight += getPaddingTop() + getPaddingBottom();

        Drawable drawable = getBackground();
        if (drawable != null) {
            maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
            maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
        }

        setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
                resolveSize(maxHeight, heightMeasureSpec));
    }

    private void drawPict(Canvas canvas, int x, int y, int w, int h,
                          float sx, float sy) {
        canvas.save();
        canvas.translate(x, y);
        canvas.clipRect(0, 0, w, h);
        canvas.scale(0.5f, 0.5f);
        canvas.scale(sx, sy, w, h);
        canvas.drawPicture(mPicture);
        canvas.restore();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
        mPicture.endRecording();

        int x = getWidth()/2;
        int y = getHeight()/2;

        if (false) {
            canvas.drawPicture(mPicture);
        } else {
            drawPict(canvas, 0, 0, x, y,  1,  1);
            drawPict(canvas, x, 0, x, y, -1,  1);
            drawPict(canvas, 0, y, x, y,  1, -1);
            drawPict(canvas, x, y, x, y, -1, -1);
        }
    }

    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        location[0] = getLeft();
        location[1] = getTop();
        dirty.set(0, 0, getWidth(), getHeight());
        return getParent();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = super.getChildCount();

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final int childLeft = getPaddingLeft();
                final int childTop = getPaddingTop();
                child.layout(childLeft, childTop,
                        childLeft + child.getMeasuredWidth(),
                        childTop + child.getMeasuredHeight());

            }
        }
    }
}
Using PorterDuffXfermode
package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Xfermodes extends GraphicsActivity {
  // create a bitmap with a circle, used for the "dst" image
  static Bitmap makeDst(int w, int h) {
    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bm);
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

    p.setColor(0xFFFFCC44);
    c.drawOval(new RectF(0, 0, w * 3 / 4, h * 3 / 4), p);
    return bm;
  }

  // create a bitmap with a rect, used for the "src" image
  static Bitmap makeSrc(int w, int h) {
    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bm);
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

    p.setColor(0xFF66AAFF);
    c.drawRect(w / 3, h / 3, w * 19 / 20, h * 19 / 20, p);
    return bm;
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private static final int W = 64;
    private static final int H = 64;
    private static final int ROW_MAX = 4; // number of samples per row

    private Bitmap mSrcB;
    private Bitmap mDstB;
    private Shader mBG; // background checker-board pattern

    private static final Xfermode[] sModes = {
        new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
        new PorterDuffXfermode(PorterDuff.Mode.SRC),
        new PorterDuffXfermode(PorterDuff.Mode.DST),
        new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
        new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
        new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
        new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
        new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
        new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
        new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
        new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
        new PorterDuffXfermode(PorterDuff.Mode.XOR),
        new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
        new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
        new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
        new PorterDuffXfermode(PorterDuff.Mode.SCREEN) };

    private static final String[] sLabels = { "Clear", "Src", "Dst",
        "SrcOver", "DstOver", "SrcIn", "DstIn", "SrcOut", "DstOut",
        "SrcATop", "DstATop", "Xor", "Darken", "Lighten", "Multiply",
        "Screen" };

    public SampleView(Context context) {
      super(context);

      mSrcB = makeSrc(W, H);
      mDstB = makeDst(W, H);

      // make a ckeckerboard pattern
      Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC,
          0xFFCCCCCC, 0xFFFFFFFF }, 2, 2, Bitmap.Config.RGB_565);
      mBG = new BitmapShader(bm, Shader.TileMode.REPEAT,
          Shader.TileMode.REPEAT);
      Matrix m = new Matrix();
      m.setScale(6, 6);
      mBG.setLocalMatrix(m);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(Color.WHITE);

      Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);
      labelP.setTextAlign(Paint.Align.CENTER);

      Paint paint = new Paint();
      paint.setFilterBitmap(false);

      canvas.translate(15, 35);

      int x = 0;
      int y = 0;
      for (int i = 0; i < sModes.length; i++) {
        // draw the border
        paint.setStyle(Paint.Style.STROKE);
        paint.setShader(null);
        canvas.drawRect(x - 0.5f, y - 0.5f, x + W + 0.5f, y + H + 0.5f,
            paint);

        // draw the checker-board pattern
        paint.setStyle(Paint.Style.FILL);
        paint.setShader(mBG);
        canvas.drawRect(x, y, x + W, y + H, paint);

        // draw the src/dst example into our offscreen bitmap
        int sc = canvas.saveLayer(x, y, x + W, y + H, null,
            Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG
                | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
                | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
                | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
        canvas.translate(x, y);
        canvas.drawBitmap(mDstB, 0, 0, paint);
        paint.setXfermode(sModes[i]);
        canvas.drawBitmap(mSrcB, 0, 0, paint);
        paint.setXfermode(null);
        canvas.restoreToCount(sc);

        // draw the label
        canvas.drawText(sLabels[i], x + W / 2, y - labelP.getTextSize()
            / 2, labelP);

        x += W + 10;

        // wrap around when we've drawn enough for one row
        if ((i % ROW_MAX) == ROW_MAX - 1) {
          x = 0;
          y += H + 30;
        }
      }
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

Region


package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.RegionIterator;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private final Paint mPaint = new Paint();
    private final Rect mRect1 = new Rect();
    private final Rect mRect2 = new Rect();

    public SampleView(Context context) {
      super(context);
      setFocusable(true);

      mPaint.setAntiAlias(true);
      mPaint.setTextSize(16);
      mPaint.setTextAlign(Paint.Align.CENTER);

      mRect1.set(10, 10, 100, 80);
      mRect2.set(50, 50, 130, 110);
    }

    private void drawOriginalRects(Canvas canvas, int alpha) {
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setColor(Color.RED);
      mPaint.setAlpha(alpha);
      drawCentered(canvas, mRect1, mPaint);
      mPaint.setColor(Color.BLUE);
      mPaint.setAlpha(alpha);
      drawCentered(canvas, mRect2, mPaint);

      // restore style
      mPaint.setStyle(Paint.Style.FILL);
    }

    private void drawRgn(Canvas canvas, int color, String str, Region.Op op) {
      if (str != null) {
        mPaint.setColor(Color.BLACK);
        canvas.drawText(str, 80, 24, mPaint);
      }

      Region rgn = new Region();
      rgn.set(mRect1);
      rgn.op(mRect2, op);

      mPaint.setColor(color);
      RegionIterator iter = new RegionIterator(rgn);
      Rect r = new Rect();

      canvas.translate(0, 30);
      mPaint.setColor(color);
      while (iter.next(r)) {
        canvas.drawRect(r, mPaint);
      }
      drawOriginalRects(canvas, 0x80);
    }

    private static void drawCentered(Canvas c, Rect r, Paint p) {
      float inset = p.getStrokeWidth() * 0.5f;
      if (inset == 0) { // catch hairlines
        inset = 0.5f;
      }
      c.drawRect(r.left + inset, r.top + inset, r.right - inset, r.bottom
          - inset, p);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(Color.GRAY);

      canvas.save();
      canvas.translate(80, 5);
      drawOriginalRects(canvas, 0xFF);
      canvas.restore();

      mPaint.setStyle(Paint.Style.FILL);

      canvas.save();
      canvas.translate(0, 140);
      drawRgn(canvas, Color.RED, "Union", Region.Op.UNION);
      canvas.restore();

      canvas.save();
      canvas.translate(0, 280);
      drawRgn(canvas, Color.BLUE, "Xor", Region.Op.XOR);
      canvas.restore();

      canvas.save();
      canvas.translate(160, 140);
      drawRgn(canvas, Color.GREEN, "Difference", Region.Op.DIFFERENCE);
      canvas.restore();

      canvas.save();
      canvas.translate(160, 280);
      drawRgn(canvas, Color.WHITE, "Intersect", Region.Op.INTERSECT);
      canvas.restore();
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

Stroke

Set Stroke Width

 

package app.Test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.os.Bundle;
import android.view.View;

public class appTest extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new GraphicsView(this));
  }
  static public class GraphicsView extends View {
    private static final String QUOTE = "This is a test. This is a demo.";
    private Path circle;
    private Paint cPaint;
    private Paint tPaint;

    public GraphicsView(Context context) {
      super(context);

      int color = Color.BLUE; 

      circle = new Path();
      circle.addCircle(150, 150, 100, Direction.CW);

      cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      cPaint.setStyle(Paint.Style.STROKE);
      cPaint.setColor(Color.LTGRAY);
      cPaint.setStrokeWidth(3);

      setBackgroundResource(R.drawable.icon);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawPath(circle, cPaint);
    }
  }
}


//main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="@drawable/icon">
   <org.example.graphics.Graphics.GraphicsView
      android:id="@+id/graphics"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" />
</LinearLayout>


//strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Graphics</string>

</resources>


//colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="mycolor">#7fff00ff</color> 
</resources>

Set stroke size

 
package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStrokeWidth(100);
    canvas.drawPoint(199, 201, paint);

  }
}

Thumbnail

//package com.birbeck.wallpaperslideshow;

import android.graphics.Bitmap;

class ThumbnailUtilsWrapper {

  static {
    try {
      Class.forName("android.media.ThumbnailUtils");
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  
  public static void checkAvailable() { }

  public static Bitmap extractThumbnail(final Bitmap source, final int width,
      final int height) {
    return android.media.ThumbnailUtils.extractThumbnail(source, width,
        height, android.media.ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
  }

}

Circle

package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    // Circle

    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStyle(Paint.Style.STROKE);
    float x = 50;
    float y = 50;
    float radius = 20;
    canvas.drawCircle(x, y, radius, paint);

  }
}

Line

Draw a line

  

package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    // Line
    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStrokeWidth(10);
    int startx = 50;
    int starty = 100;
    int endx = 150;
    int endy = 210;
    canvas.drawLine(startx, starty, endx, endy, paint);

  }
}

Smooth Line

  
// Created by plusminus on 13:24:05 - 21.09.2008
//package org.andnav2.osm.util;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

class Util {
  public static final String DEBUGTAG = "OPENSTREETMAP";

  public static final String BASEPATH_ON_EXTERNAL_MEDIA = "andnav2/";

  public static final String SDCARD_SAVEDROUTES_PATH = "routes/";
  public static final String SDCARD_SAVEDTRACES_PATH = "traces/";
  public static final String SDCARD_SKYHOOKCACHE_PATH = "skyhookcache/";
  public static final String SDCARD_TILE_PATH = "tiles/";

  public static final int NOT_SET = Integer.MIN_VALUE;

  public static final int Y = 0;
  public static final int X = 1;


  /**
   * 
   * @param pOrderedPoints Ordered means that the points are placed as if they are a line.
   */
  public static void smoothLine(final Set<ValuePair> pPointsInLineorder){
    ValuePair prev = null;
    ValuePair cur;

    /* We want only uniqe new values. */
    final Set<ValuePair> newPoints = new TreeSet<ValuePair>(new Comparator<ValuePair>(){
      @Override
      public int compare(final ValuePair a, final ValuePair b) {
        return a.compareTo(b);
      }
    });

    for(final Iterator<ValuePair> lineIterator = pPointsInLineorder.iterator(); lineIterator.hasNext(); ) {
      cur = lineIterator.next();

      if(prev != null){
        final int difA = cur.a - prev.a;
        final int difB = cur.b - prev.b;
        /* Check if we have a diagonal jump, like: (See X's)
         * 
         *      X----
         * ----X
         * 
         * */
        if(Math.abs(difA) == 1 && Math.abs(difB) == 1){
          /* Add two new points (See O's)
           * 
           *     0X----
           * ----X0
           * 
           */
          newPoints.add(new ValuePair(cur.a, prev.b));
          newPoints.add(new ValuePair(prev.a, cur.b));
        }
      }

      prev = cur;
    }

    pPointsInLineorder.addAll(newPoints);
  }}
class ValuePair implements Comparable<ValuePair>{
  //          
  // Constants
  //          

  //          
  // Fields
  //          

  final int a,b;

  //          
  // Constructors
  //          

  public ValuePair(final int[] reuse) {
    this.a = reuse[0];
    this.b = reuse[1];
  }

  public ValuePair(final int pA, final int pB) {
    this.a = pA;
    this.b = pB;
  }

  //          
  // Getter & Setter
  //          

  public int[] toArray() {
    return new int[]{this.a,this.b};
  }

  public int getValueA() {
    return this.a;
  }

  public int getValueB() {
    return this.b;
  }

  //          
  // Methods from SuperClass/Interfaces
  //          

  @Override
  public boolean equals(final Object o) {
    return o instanceof ValuePair
    && this.a == ((ValuePair)o).a
    && this.b == ((ValuePair)o).b;
  }

  @Override
  public int compareTo(final ValuePair another) {
    if(this.a != another.a) {
      return this.a - another.a;
    } else if(this.b != another.b) {
      return this.b - another.b;
    } else {
      return 0;
    }
  }

  //          
  // Methods
  //          
}

Raster Line

  
// Created by plusminus on 13:24:05 - 21.09.2008
//package org.andnav2.osm.util;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

class Util {
  public static final String DEBUGTAG = "OPENSTREETMAP";

  public static final String BASEPATH_ON_EXTERNAL_MEDIA = "andnav2/";

  public static final String SDCARD_SAVEDROUTES_PATH = "routes/";
  public static final String SDCARD_SAVEDTRACES_PATH = "traces/";
  public static final String SDCARD_SKYHOOKCACHE_PATH = "skyhookcache/";
  public static final String SDCARD_TILE_PATH = "tiles/";

  public static final int NOT_SET = Integer.MIN_VALUE;

  public static final int Y = 0;
  public static final int X = 1;


  /**
   * @see http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
   */
  public static void rasterLine(int x0, int y0, int x1, int y1, final PixelSetter raster) {
    int dy = y1 - y0;
    int dx = x1 - x0;
    int stepx, stepy;

    if (dy < 0) {
      dy = -dy;
      stepy = -1;
    } else {
      stepy = 1;
    }
    if (dx < 0) {
      dx = -dx;
      stepx = -1;
    } else {
      stepx = 1;
    }

    raster.setPixel(x0, y0);
    raster.setPixel(x1, y1);
    if (dx > dy) {
      final int length = (dx - 1) >> 2;
    final int extras = (dx - 1) & 3;
    final int incr2 = (dy << 2) - (dx << 1);
    if (incr2 < 0) {
      final int c = dy << 1;
      final int incr1 = c << 1;
      int d = incr1 - dx;
      for (int i = 0; i < length; i++) {
        x0 += stepx;
        x1 -= stepx;
        if (d < 0) {                   // Pattern:
          raster.setPixel(x0, y0);           //
          raster.setPixel(x0 += stepx, y0);       // x o o
          raster.setPixel(x1, y1);           //
          raster.setPixel(x1 -= stepx, y1);
          d += incr1;
        } else {
          if (d < c) {                   // Pattern:
            raster.setPixel(x0, y0);           // o
            raster.setPixel(x0 += stepx, y0 += stepy);   // x o
            raster.setPixel(x1, y1);           //
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          } else {
            raster.setPixel(x0, y0 += stepy);       // Pattern:
            raster.setPixel(x0 += stepx, y0);       // o o
            raster.setPixel(x1, y1 -= stepy);       // x
            raster.setPixel(x1 -= stepx, y1);       //
          }
          d += incr2;
        }
      }
      if (extras > 0) {
        if (d < 0) {
          raster.setPixel(x0 += stepx, y0);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1);
          }
        } else if (d < c) {
          raster.setPixel(x0 += stepx, y0);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1);
          }
        } else {
          raster.setPixel(x0 += stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          }
        }
      }
    } else {
      final int c = (dy - dx) << 1;
      final int incr1 = c << 1;
      int d = incr1 + dx;
      for (int i = 0; i < length; i++) {
        x0 += stepx;
        x1 -= stepx;
        if (d > 0) {
          raster.setPixel(x0, y0 += stepy);         // Pattern:
          raster.setPixel(x0 += stepx, y0 += stepy);     // o
          raster.setPixel(x1, y1 -= stepy);         // o
          raster.setPixel(x1 -= stepx, y1 -= stepy);     // x
          d += incr1;
        } else {
          if (d < c) {
            raster.setPixel(x0, y0);             // Pattern:
            raster.setPixel(x0 += stepx, y0 += stepy);     // o
            raster.setPixel(x1, y1);             // x o
            raster.setPixel(x1 -= stepx, y1 -= stepy);    //
          } else {
            raster.setPixel(x0, y0 += stepy);     // Pattern:
            raster.setPixel(x0 += stepx, y0);     // o o
            raster.setPixel(x1, y1 -= stepy);     // x
            raster.setPixel(x1 -= stepx, y1);     //
          }
          d += incr2;
        }
      }
      if (extras > 0) {
        if (d > 0) {
          raster.setPixel(x0 += stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          }
        } else if (d < c) {
          raster.setPixel(x0 += stepx, y0);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1);
          }
        } else {
          raster.setPixel(x0 += stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0);
          }
          if (extras > 2) {
            if (d > c) {
              raster.setPixel(x1 -= stepx, y1 -= stepy);
            } else {
              raster.setPixel(x1 -= stepx, y1);
            }
          }
        }
      }
    }
    } else {
      final int length = (dy - 1) >> 2;
    final int extras = (dy - 1) & 3;
    final int incr2 = (dx << 2) - (dy << 1);
    if (incr2 < 0) {
      final int c = dx << 1;
      final int incr1 = c << 1;
      int d = incr1 - dy;
      for (int i = 0; i < length; i++) {
        y0 += stepy;
        y1 -= stepy;
        if (d < 0) {
          raster.setPixel(x0, y0);
          raster.setPixel(x0, y0 += stepy);
          raster.setPixel(x1, y1);
          raster.setPixel(x1, y1 -= stepy);
          d += incr1;
        } else {
          if (d < c) {
            raster.setPixel(x0, y0);
            raster.setPixel(x0 += stepx, y0 += stepy);
            raster.setPixel(x1, y1);
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          } else {
            raster.setPixel(x0 += stepx, y0);
            raster.setPixel(x0, y0 += stepy);
            raster.setPixel(x1 -= stepx, y1);
            raster.setPixel(x1, y1 -= stepy);
          }
          d += incr2;
        }
      }
      if (extras > 0) {
        if (d < 0) {
          raster.setPixel(x0, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1, y1 -= stepy);
          }
        } else if (d < c) {
          raster.setPixel(stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1, y1 -= stepy);
          }
        } else {
          raster.setPixel(x0 += stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          }
        }
      }
    } else {
      final int c = (dx - dy) << 1;
      final int incr1 = c << 1;
      int d = incr1 + dy;
      for (int i = 0; i < length; i++) {
        y0 += stepy;
        y1 -= stepy;
        if (d > 0) {
          raster.setPixel(x0 += stepx, y0);
          raster.setPixel(x0 += stepx, y0 += stepy);
          raster.setPixel(x1 -= stepy, y1);
          raster.setPixel(x1 -= stepx, y1 -= stepy);
          d += incr1;
        } else {
          if (d < c) {
            raster.setPixel(x0, y0);
            raster.setPixel(x0 += stepx, y0 += stepy);
            raster.setPixel(x1, y1);
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          } else {
            raster.setPixel(x0 += stepx, y0);
            raster.setPixel(x0, y0 += stepy);
            raster.setPixel(x1 -= stepx, y1);
            raster.setPixel(x1, y1 -= stepy);
          }
          d += incr2;
        }
      }
      if (extras > 0) {
        if (d > 0) {
          raster.setPixel(x0 += stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1 -= stepx, y1 -= stepy);
          }
        } else if (d < c) {
          raster.setPixel(x0, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0 += stepx, y0 += stepy);
          }
          if (extras > 2) {
            raster.setPixel(x1, y1 -= stepy);
          }
        } else {
          raster.setPixel(x0 += stepx, y0 += stepy);
          if (extras > 1) {
            raster.setPixel(x0, y0 += stepy);
          }
          if (extras > 2) {
            if (d > c) {
              raster.setPixel(x1 -= stepx, y1 -= stepy);
            } else {
              raster.setPixel(x1, y1 -= stepy);
            }
          }
        }
      }
    }
    }
  }

  //          
  // Inner and Anonymous Classes
  //          

  public static interface PixelSetter {
    public void setPixel(final int x, final int y);
  }

}

Draw Picture

package app.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Pictures extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private Picture mPicture;
    private Drawable mDrawable;

    static void drawSomething(Canvas canvas) {
      Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

      p.setColor(0x88FF0000);
      canvas.drawCircle(50, 50, 40, p);

      p.setColor(Color.GREEN);
      p.setTextSize(30);
      canvas.drawText("Pictures", 60, 60, p);
    }

    public SampleView(Context context) {
      super(context);
      setFocusable(true);
      setFocusableInTouchMode(true);

      mPicture = new Picture();
      drawSomething(mPicture.beginRecording(200, 100));
      mPicture.endRecording();

      mDrawable = new PictureDrawable(mPicture);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(Color.WHITE);

      canvas.drawPicture(mPicture);

      canvas.drawPicture(mPicture, new RectF(0, 100, getWidth(), 200));

      mDrawable.setBounds(0, 200, getWidth(), 300);
      mDrawable.draw(canvas);

      ByteArrayOutputStream os = new ByteArrayOutputStream();
      mPicture.writeToStream(os);
      InputStream is = new ByteArrayInputStream(os.toByteArray());
      canvas.translate(0, 300);
      canvas.drawPicture(Picture.createFromStream(is));
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

Draw Polygon

package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    private static class SampleView extends View {
        private Paint   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private Matrix  mMatrix = new Matrix();
        private Paint.FontMetrics mFontMetrics;

        private void doDraw(Canvas canvas, float src[], float dst[]) {
            canvas.save();
            mMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
            canvas.concat(mMatrix);

            mPaint.setColor(Color.GRAY);
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawRect(0, 0, 64, 64, mPaint);
            canvas.drawLine(0, 0, 64, 64, mPaint);
            canvas.drawLine(0, 64, 64, 0, mPaint);

            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.FILL);
            // how to draw the text center on our square
            // centering in X is easy... use alignment (and X at midpoint)
            float x = 64/2;
            // centering in Y, we need to measure ascent/descent first
            float y = 64/2 - (mFontMetrics.ascent + mFontMetrics.descent)/2;
            canvas.drawText(src.length/2 + "", x, y, mPaint);

            canvas.restore();
        }

        public SampleView(Context context) {
            super(context);

            // for when the style is STROKE
            mPaint.setStrokeWidth(4);
            // for when we draw text
            mPaint.setTextSize(40);
            mPaint.setTextAlign(Paint.Align.CENTER);
            mFontMetrics = mPaint.getFontMetrics();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);

            canvas.save();
            canvas.translate(10, 10);
            // translate (1 point)
            doDraw(canvas, new float[] { 0, 0 }, new float[] { 5, 5 });
            canvas.restore();

            canvas.save();
            canvas.translate(160, 10);
            // rotate/uniform-scale (2 points)
            doDraw(canvas, new float[] { 32, 32, 64, 32 },
                           new float[] { 32, 32, 64, 48 });
            canvas.restore();

            canvas.save();
            canvas.translate(10, 110);
            // rotate/skew (3 points)
            doDraw(canvas, new float[] { 0, 0, 64, 0, 0, 64 },
                           new float[] { 0, 0, 96, 0, 24, 64 });
            canvas.restore();

            canvas.save();
            canvas.translate(160, 110);
            // perspective (4 points)
            doDraw(canvas, new float[] { 0, 0, 64, 0, 64, 64, 0, 64 },
                           new float[] { 0, 0, 96, 0, 64, 96, 0, 64 });
            canvas.restore();
        }
    }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

   

rectangle

Draw a rectangle

 

package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    // Rectangle

    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    paint.setStrokeWidth(10);
    float leftx = 20;
    float topy = 20;
    float rightx = 50;
    float bottomy = 100;
    canvas.drawRect(leftx, topy, rightx, bottomy, paint);

  }
}

Draw a rectangle with float values

 
package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    // RectF Rectangle

    Paint paint = new Paint();
    float leftx = 20;
    float topy = 20;
    float rightx = 50;
    float bottomy = 100;
    RectF rectangle = new RectF(leftx, topy, rightx, bottomy);
    canvas.drawRect(rectangle, paint);

  }
}

Round Rectangles

package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class Test extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private Path mPath;
    private Paint mPaint;
    private Rect mRect;
    private GradientDrawable mDrawable;

    public SampleView(Context context) {
      super(context);
      setFocusable(true);

      mPath = new Path();
      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mRect = new Rect(0, 0, 120, 120);

      mDrawable = new GradientDrawable(
          GradientDrawable.Orientation.TL_BR, new int[] { 0xFFFF0000,
              0xFF00FF00, 0xFF0000FF });
      mDrawable.setShape(GradientDrawable.RECTANGLE);
      mDrawable.setGradientRadius((float) (Math.sqrt(2) * 60));
    }

    static void setCornerRadii(GradientDrawable drawable, float r0,
        float r1, float r2, float r3) {
      drawable.setCornerRadii(new float[] { r0, r0, r1, r1, r2, r2, r3,
          r3 });
    }

    @Override
    protected void onDraw(Canvas canvas) {

      mDrawable.setBounds(mRect);

      float r = 16;

      canvas.save();
      canvas.translate(10, 10);
      mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
      setCornerRadii(mDrawable, r, r, 0, 0);
      mDrawable.draw(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(10 + mRect.width() + 10, 10);
      mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
      setCornerRadii(mDrawable, 0, 0, r, r);
      mDrawable.draw(canvas);
      canvas.restore();

      canvas.translate(0, mRect.height() + 10);

      canvas.save();
      canvas.translate(10, 10);
      mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
      setCornerRadii(mDrawable, 0, r, r, 0);
      mDrawable.draw(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(10 + mRect.width() + 10, 10);
      mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
      setCornerRadii(mDrawable, r, 0, 0, r);
      mDrawable.draw(canvas);
      canvas.restore();

      canvas.translate(0, mRect.height() + 10);

      canvas.save();
      canvas.translate(10, 10);
      mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
      setCornerRadii(mDrawable, r, 0, r, 0);
      mDrawable.draw(canvas);
      canvas.restore();

      canvas.save();
      canvas.translate(10 + mRect.width() + 10, 10);
      mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
      setCornerRadii(mDrawable, 0, r, 0, r);
      mDrawable.draw(canvas);
      canvas.restore();
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

ShapeDrawable

Bouncing Ball


package com.example.android.apis.animation;

// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import android.graphics.drawable.ColorDrawable;
import com.example.android.apis.R;

import android.animation.*;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;

import java.util.ArrayList;


import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.view.View;

/**
 * A data structure that holds a Shape and various properties that can be used to define
 * how the shape is drawn.
 */
 class ShapeHolder {
    private float x = 0, y = 0;
    private ShapeDrawable shape;
    private int color;
    private RadialGradient gradient;
    private float alpha = 1f;
    private Paint paint;

    public void setPaint(Paint value) {
        paint = value;
    }
    public Paint getPaint() {
        return paint;
    }

    public void setX(float value) {
        x = value;
    }
    public float getX() {
        return x;
    }
    public void setY(float value) {
        y = value;
    }
    public float getY() {
        return y;
    }
    public void setShape(ShapeDrawable value) {
        shape = value;
    }
    public ShapeDrawable getShape() {
        return shape;
    }
    public int getColor() {
        return color;
    }
    public void setColor(int value) {
        shape.getPaint().setColor(value);
        color = value;
    }
    public void setGradient(RadialGradient value) {
        gradient = value;
    }
    public RadialGradient getGradient() {
        return gradient;
    }

    public void setAlpha(float alpha) {
        this.alpha = alpha;
        shape.setAlpha((int)((alpha * 255f) + .5f));
    }

    public float getWidth() {
        return shape.getShape().getWidth();
    }
    public void setWidth(float width) {
        Shape s = shape.getShape();
        s.resize(width, s.getHeight());
    }

    public float getHeight() {
        return shape.getShape().getHeight();
    }
    public void setHeight(float height) {
        Shape s = shape.getShape();
        s.resize(s.getWidth(), height);
    }

    public ShapeHolder(ShapeDrawable s) {
        shape = s;
    }
}

public class BouncingBalls extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LinearLayout container = (LinearLayout) findViewById(R.id.container);
        container.addView(new MyAnimationView(this));
    }

    public class MyAnimationView extends View {

        private static final int RED = 0xffFF8080;
        private static final int BLUE = 0xff8080FF;
        private static final int CYAN = 0xff80ffff;
        private static final int GREEN = 0xff80ff80;

        public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
        AnimatorSet animation = null;

        public MyAnimationView(Context context) {
            super(context);

            // Animate background color
            // Note that setting the background color will automatically invalidate the
            // view, so that the animated color, and the bouncing balls, get redisplayed on
            // every frame of the animation.
            ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
            colorAnim.setDuration(3000);
            colorAnim.setEvaluator(new ArgbEvaluator());
            colorAnim.setRepeatCount(ValueAnimator.INFINITE);
            colorAnim.setRepeatMode(ValueAnimator.REVERSE);
            colorAnim.start();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction() != MotionEvent.ACTION_DOWN &&
                    event.getAction() != MotionEvent.ACTION_MOVE) {
                return false;
            }
            ShapeHolder newBall = addBall(event.getX(), event.getY());

            // Bouncing animation with squash and stretch
            float startY = newBall.getY();
            float endY = getHeight() - 50f;
            float h = (float)getHeight();
            float eventY = event.getY();
            int duration = (int)(500 * ((h - eventY)/h));
            ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);
            bounceAnim.setDuration(duration);
            bounceAnim.setInterpolator(new AccelerateInterpolator());
            ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", newBall.getX(),
                    newBall.getX() - 25f);
            squashAnim1.setDuration(duration/4);
            squashAnim1.setRepeatCount(1);
            squashAnim1.setRepeatMode(ValueAnimator.REVERSE);
            squashAnim1.setInterpolator(new DecelerateInterpolator());
            ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", newBall.getWidth(),
                    newBall.getWidth() + 50);
            squashAnim2.setDuration(duration/4);
            squashAnim2.setRepeatCount(1);
            squashAnim2.setRepeatMode(ValueAnimator.REVERSE);
            squashAnim2.setInterpolator(new DecelerateInterpolator());
            ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY,
                    endY + 25f);
            stretchAnim1.setDuration(duration/4);
            stretchAnim1.setRepeatCount(1);
            stretchAnim1.setInterpolator(new DecelerateInterpolator());
            stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);
            ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",
                    newBall.getHeight(), newBall.getHeight() - 25);
            stretchAnim2.setDuration(duration/4);
            stretchAnim2.setRepeatCount(1);
            stretchAnim2.setInterpolator(new DecelerateInterpolator());
            stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);
            ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY,
                    startY);
            bounceBackAnim.setDuration(duration);
            bounceBackAnim.setInterpolator(new DecelerateInterpolator());
            // Sequence the down/squash&stretch/up animations
            AnimatorSet bouncer = new AnimatorSet();
            bouncer.play(bounceAnim).before(squashAnim1);
            bouncer.play(squashAnim1).with(squashAnim2);
            bouncer.play(squashAnim1).with(stretchAnim1);
            bouncer.play(squashAnim1).with(stretchAnim2);
            bouncer.play(bounceBackAnim).after(stretchAnim2);

            // Fading animation - remove the ball when the animation is done
            ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
            fadeAnim.setDuration(250);
            fadeAnim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    balls.remove(((ObjectAnimator)animation).getTarget());

                }
            });

            // Sequence the two animations to play one after the other
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.play(bouncer).before(fadeAnim);

            // Start the animation
            animatorSet.start();

            return true;
        }

        private ShapeHolder addBall(float x, float y) {
            OvalShape circle = new OvalShape();
            circle.resize(50f, 50f);
            ShapeDrawable drawable = new ShapeDrawable(circle);
            ShapeHolder shapeHolder = new ShapeHolder(drawable);
            shapeHolder.setX(x - 25f);
            shapeHolder.setY(y - 25f);
            int red = (int)(Math.random() * 255);
            int green = (int)(Math.random() * 255);
            int blue = (int)(Math.random() * 255);
            int color = 0xff000000 | red << 16 | green << 8 | blue;
            Paint paint = drawable.getPaint(); //new Paint(Paint.ANTI_ALIAS_FLAG);
            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
            RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
                    50f, color, darkColor, Shader.TileMode.CLAMP);
            paint.setShader(gradient);
            shapeHolder.setPaint(paint);
            balls.add(shapeHolder);
            return shapeHolder;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            for (int i = 0; i < balls.size(); ++i) {
                ShapeHolder shapeHolder = balls.get(i);
                canvas.save();
                canvas.translate(shapeHolder.getX(), shapeHolder.getY());
                shapeHolder.getShape().draw(canvas);
                canvas.restore();
            }
        }
    }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/container"
    >
</LinearLayout>