Android Tutorial - 2D Graphics : Drawable

 Animate Drawables

package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Picture;
import android.graphics.PixelFormat;
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;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;

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 AnimateDrawable mDrawable;

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

      Drawable dr = context.getResources().getDrawable(R.drawable.icon);
      dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());

      Animation an = new TranslateAnimation(0, 100, 0, 200);
      an.setDuration(2000);
      an.setRepeatCount(-1);
      an.initialize(10, 10, 10, 10);

      mDrawable = new AnimateDrawable(dr, an);
      an.startNow();
    }

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

      mDrawable.draw(canvas);
      invalidate();
    }
  }
}

class ProxyDrawable extends Drawable {

  private Drawable mProxy;
  private boolean mMutated;

  public ProxyDrawable(Drawable target) {
    mProxy = target;
  }

  public Drawable getProxy() {
    return mProxy;
  }

  public void setProxy(Drawable proxy) {
    if (proxy != this) {
      mProxy = proxy;
    }
  }

  @Override
  public void draw(Canvas canvas) {
    if (mProxy != null) {
      mProxy.draw(canvas);
    }
  }

  @Override
  public int getIntrinsicWidth() {
    return mProxy != null ? mProxy.getIntrinsicWidth() : -1;
  }

  @Override
  public int getIntrinsicHeight() {
    return mProxy != null ? mProxy.getIntrinsicHeight() : -1;
  }

  @Override
  public int getOpacity() {
    return mProxy != null ? mProxy.getOpacity() : PixelFormat.TRANSPARENT;
  }

  @Override
  public void setFilterBitmap(boolean filter) {
    if (mProxy != null) {
      mProxy.setFilterBitmap(filter);
    }
  }

  @Override
  public void setDither(boolean dither) {
    if (mProxy != null) {
      mProxy.setDither(dither);
    }
  }

  @Override
  public void setColorFilter(ColorFilter colorFilter) {
    if (mProxy != null) {
      mProxy.setColorFilter(colorFilter);
    }
  }

  @Override
  public void setAlpha(int alpha) {
    if (mProxy != null) {
      mProxy.setAlpha(alpha);
    }
  }

  @Override
  public Drawable mutate() {
    if (mProxy != null && !mMutated && super.mutate() == this) {
      mProxy.mutate();
      mMutated = true;
    }
    return this;
  }
}

class AnimateDrawable extends ProxyDrawable {

  private Animation mAnimation;
  private Transformation mTransformation = new Transformation();

  public AnimateDrawable(Drawable target) {
    super(target);
  }

  public AnimateDrawable(Drawable target, Animation animation) {
    super(target);
    mAnimation = animation;
  }

  public Animation getAnimation() {
    return mAnimation;
  }

  public void setAnimation(Animation anim) {
    mAnimation = anim;
  }

  public boolean hasStarted() {
    return mAnimation != null && mAnimation.hasStarted();
  }

  public boolean hasEnded() {
    return mAnimation == null || mAnimation.hasEnded();
  }

  @Override
  public void draw(Canvas canvas) {
    Drawable dr = getProxy();
    if (dr != null) {
      int sc = canvas.save();
      Animation anim = mAnimation;
      if (anim != null) {
        anim.getTransformation(
            AnimationUtils.currentAnimationTimeMillis(),
            mTransformation);
        canvas.concat(mTransformation.getMatrix());
      }
      dr.draw(canvas);
      canvas.restoreToCount(sc);
    }
  }
}

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 Demo

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.ComposePathEffect;
import android.graphics.CornerPathEffect;
import android.graphics.DiscretePathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.ArcShape;
import android.graphics.drawable.shapes.OvalShape;
import android.graphics.drawable.shapes.PathShape;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.drawable.shapes.RoundRectShape;
import android.graphics.drawable.shapes.Shape;
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 ShapeDrawable[] mDrawables;

    private static Shader makeSweep() {
      return new SweepGradient(150, 25, new int[] { 0xFFFF0000,
          0xFF00FF00, 0xFF0000FF, 0xFFFF0000 }, null);
    }

    private static Shader makeLinear() {
      return new LinearGradient(0, 0, 50, 50, new int[] { 0xFFFF0000,
          0xFF00FF00, 0xFF0000FF }, null, Shader.TileMode.MIRROR);
    }

    private static Shader makeTiling() {
      int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0 };
      Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
          Bitmap.Config.ARGB_8888);

      return new BitmapShader(bm, Shader.TileMode.REPEAT,
          Shader.TileMode.REPEAT);
    }

    private static class MyShapeDrawable extends ShapeDrawable {
      private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

      public MyShapeDrawable(Shape s) {
        super(s);
        mStrokePaint.setStyle(Paint.Style.STROKE);
      }

      public Paint getStrokePaint() {
        return mStrokePaint;
      }

      @Override
      protected void onDraw(Shape s, Canvas c, Paint p) {
        s.draw(c, p);
        s.draw(c, mStrokePaint);
      }
    }

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

      float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
      RectF inset = new RectF(6, 6, 6, 6);
      float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };

      Path path = new Path();
      path.moveTo(50, 0);
      path.lineTo(0, 50);
      path.lineTo(50, 100);
      path.lineTo(100, 50);
      path.close();

      mDrawables = new ShapeDrawable[7];
      mDrawables[0] = new ShapeDrawable(new RectShape());
      mDrawables[1] = new ShapeDrawable(new OvalShape());
      mDrawables[2] = new ShapeDrawable(new RoundRectShape(outerR, null,
          null));
      mDrawables[3] = new ShapeDrawable(new RoundRectShape(outerR, inset,
          null));
      mDrawables[4] = new ShapeDrawable(new RoundRectShape(outerR, inset,
          innerR));
      mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
      mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));

      mDrawables[0].getPaint().setColor(0xFFFF0000);
      mDrawables[1].getPaint().setColor(0xFF00FF00);
      mDrawables[2].getPaint().setColor(0xFF0000FF);
      mDrawables[3].getPaint().setShader(makeSweep());
      mDrawables[4].getPaint().setShader(makeLinear());
      mDrawables[5].getPaint().setShader(makeTiling());
      mDrawables[6].getPaint().setColor(0x88FF8844);

      PathEffect pe = new DiscretePathEffect(10, 4);
      PathEffect pe2 = new CornerPathEffect(4);
      mDrawables[3].getPaint().setPathEffect(
          new ComposePathEffect(pe2, pe));

      MyShapeDrawable msd = (MyShapeDrawable) mDrawables[6];
      msd.getStrokePaint().setStrokeWidth(4);
    }

    @Override
    protected void onDraw(Canvas canvas) {

      int x = 10;
      int y = 10;
      int width = 300;
      int height = 50;

      for (Drawable dr : mDrawables) {
        dr.setBounds(x, y, x + width, y + height);
        dr.draw(canvas);
        y += height + 5;
      }
    }
  }
}

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 GradientDrawable
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());

      }
    }
  }
}
Gets the image drawable from the url
//package org.alldroid.forum.utils;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.Log;

/**
 * @author trr4rac
 */
class UrlHelper {
  private static final String TAG = UrlHelper.class.getSimpleName ( );

  public static URL createUrl ( String base, String action ) {
    return createUrl ( base, action, "" );
  }

  public static URL createUrl ( String base, String action, String additional ) {
    try {
      return new URL ( base + action + additional );
    } catch ( MalformedURLException ex ) {
      Log.e(TAG,ex.getMessage ( ),ex);
      return null;
    }
  }

  public static Uri createUri ( String base, String action ) {
    return createUri ( base, action, "" );
  }

  public static Uri createUri ( String base, String action, String additional ) {
    return Uri.parse ( base + action + additional );
  }

  public static URLConnection createConnection ( String baseUrl, String action ) throws IOException {
    return createConnection ( baseUrl, action, "" );
  }

  public static URLConnection createConnection ( String baseUrl, String action, String additional ) throws IOException {
    return createConnection ( createUrl ( baseUrl, action, additional ).toString ( ) );
  }

  public static URLConnection createConnection ( String url ) {
    Log.d ( TAG, "Creating Connection" );
    if ( url == null || url.length ( ) == 0 ) {
      Log.e ( TAG, "Unable to create url" );
      return null;
    } else {
      Log.d ( TAG, "Created url: " + url );
      try {
        URL turl = new URL ( url );
        return turl.openConnection ( );
      } catch ( MalformedURLException e ) {
        Log.e(TAG,e.getMessage ( ),e);
      } catch ( IOException e ) {
        Log.e(TAG,e.getMessage ( ),e);
      }
      return null;
    }
  }

  /**
   * Gets the image drawable from the url
   *
   * @author dustin.jorge@gmail.com
   * @returns the Drawable image
   * @param String
   *          url The url of the image resource
   */
  public static Drawable getImageDrawable ( String url ) {
    try {
      Log.d ( TAG, "Getting Drawable for StringUrl: " + url.toString ( ) );
      return getImageDrawable ( new URL ( url ) );
    } catch ( MalformedURLException e ) {
      Log.e(TAG,e.getMessage ( ),e);
    } catch ( Exception e ) {
      Log.e(TAG,e.getMessage ( ),e);
    }

    return null;
  }

  /**
   * Gets the image drawable from the url
   *
   * @author dustin.jorge@gmail.com
   * @returns the Drawable image
   * @param Url
   *          url The url of the image resource
   */
  public static Drawable getImageDrawable ( URL url ) {
    return getImageDrawable ( url,null,null );
  }

  public static Drawable getImageDrawable ( URL url, String username, String password ) {
    Drawable d = null;
    try {
      DefaultHttpClient client = new DefaultHttpClient ( );
      HttpGet get = new HttpGet ( url.toURI ( ) );
      if ( username != null && username.length ( ) > 0 && password != null && password.length() > 0 ) {
        client.getCredentialsProvider ().setCredentials ( new AuthScope ( url.getHost (), url.getPort () ), new UsernamePasswordCredentials ( username, password ) );
      }
      HttpResponse response = client.execute ( get );
      InputStream is = response.getEntity ( ).getContent ( );
      BufferedInputStream bis = new BufferedInputStream ( is );
      String full = url.getFile ( );
      int start = full.lastIndexOf ( "/" ) + 1;
      if ( full.length ( ) > 0 ) {
        full = full.substring ( start );
      }
      d = Drawable.createFromStream ( bis, full );
      if ( d == null ) {
        Log.w ( TAG, "Drawable was null: " + full + ": " + url.toString ( ) );
      }
      bis.close ( );
      is.close ( );
    } catch ( Exception e ) {
      Log.e(TAG,e.getMessage ( ),e);
    }
    return d;
  }

}

   

Drawable.createFromStream

  
//package com.myspace.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

class MSDrawableManager {
    private final Map<String, Drawable> drawableMap;
    private ExecutorService executorService;

    static MSDrawableManager instance;
    
    static public MSDrawableManager getInstance() {
      if (instance == null) {
        synchronized(MSDrawableManager.class) {
          if (instance == null) {
            instance = new MSDrawableManager(); 
          }
        }
      }  
      return instance;
    }
    
    private MSDrawableManager() {
      drawableMap = new HashMap<String, Drawable>();
      executorService = Executors.newFixedThreadPool(2);
    }
    
    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
      if (drawableMap.containsKey(urlString)) {
        imageView.setImageDrawable(drawableMap.get(urlString));
      }
      
      imageView.setImageDrawable(null);

      final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
          imageView.setImageDrawable((Drawable) message.obj);
        }
      };

      executorService.execute(new Runnable() {
        public void run() {
          Drawable drawable = fetchDrawable(urlString);
          Message message = handler.obtainMessage(1, drawable);
          handler.sendMessage(message);
        }
      });
    }
    
    public Drawable fetchDrawable(String urlString) {
      if (drawableMap.containsKey(urlString)) {
        return drawableMap.get(urlString);
      }

      try {
        InputStream is = fetch(urlString);
        Drawable drawable = Drawable.createFromStream(is, "src");
        drawableMap.put(urlString, drawable);
        return drawable;
      } catch (Exception e) {
        return null; 
      }
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
      DefaultHttpClient httpClient = new DefaultHttpClient();
      HttpGet request = new HttpGet(urlString);
      HttpResponse response = httpClient.execute(request);
      return response.getEntity().getContent();
    }
}

Drawable Manager

  
//package com.myspace.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

class MSDrawableManager {
    private final Map<String, Drawable> drawableMap;
    private ExecutorService executorService;

    static MSDrawableManager instance;
    
    static public MSDrawableManager getInstance() {
      if (instance == null) {
        synchronized(MSDrawableManager.class) {
          if (instance == null) {
            instance = new MSDrawableManager(); 
          }
        }
      }  
      return instance;
    }
    
    private MSDrawableManager() {
      drawableMap = new HashMap<String, Drawable>();
      executorService = Executors.newFixedThreadPool(2);
    }
    
    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
      if (drawableMap.containsKey(urlString)) {
        imageView.setImageDrawable(drawableMap.get(urlString));
      }
      
      imageView.setImageDrawable(null);

      final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
          imageView.setImageDrawable((Drawable) message.obj);
        }
      };

      executorService.execute(new Runnable() {
        public void run() {
          Drawable drawable = fetchDrawable(urlString);
          Message message = handler.obtainMessage(1, drawable);
          handler.sendMessage(message);
        }
      });
    }
    
    public Drawable fetchDrawable(String urlString) {
      if (drawableMap.containsKey(urlString)) {
        return drawableMap.get(urlString);
      }

      try {
        InputStream is = fetch(urlString);
        Drawable drawable = Drawable.createFromStream(is, "src");
        drawableMap.put(urlString, drawable);
        return drawable;
      } catch (Exception e) {
        return null; 
      }
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
      DefaultHttpClient httpClient = new DefaultHttpClient();
      HttpGet request = new HttpGet(urlString);
      HttpResponse response = httpClient.execute(request);
      return response.getEntity().getContent();
    }
}

get Drawable From Url

  
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;

class IOUtils {

  private static final String LOG_TAG = "IOUtils";
  public static final String PREFS_FILE = "javaeye.prefs";

  public static Drawable getDrawableFromUrl(URL url) {
    try {
      InputStream is = url.openStream();
      Drawable d = Drawable.createFromStream(is, "src");
      return d;
    } catch (MalformedURLException e) {
      // e.printStackTrace();
    } catch (IOException e) {
      // e.printStackTrace();
    }
    return null;
  }

  private static void copy(InputStream in, OutputStream out)
      throws IOException {
    byte[] b = new byte[4 * 1024];
    int read;
    while ((read = in.read(b)) != -1) {
      out.write(b, 0, read);
    }
  }

  private static void closeStream(Closeable stream) {
    if (stream != null) {
      try {
        stream.close();
      } catch (IOException e) {
        // Log.e(LOG_TAG, e.getMessage());
      }
    }
  }

}

simply resizes a given drawable resource to the given width and height

  
//package com.retain;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.Date;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * @author Nazmul Idris
 * @version 1.0
 * @since Jul 8, 2008, 2:35:39 PM
 */
class AppUtils {

  /** simply resizes a given drawable resource to the given width and height */
  public static Drawable resizeImage(Context ctx, int resId, int iconWidth,
      int iconHeight) {

    // load the origial Bitmap
    Bitmap BitmapOrg = BitmapFactory.decodeResource(ctx.getResources(),
        resId);

    int width = BitmapOrg.getWidth();
    int height = BitmapOrg.getHeight();
    int newWidth = iconWidth;
    int newHeight = iconHeight;

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

    // create a matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the Bitmap
    matrix.postScale(scaleWidth, scaleHeight);

    // if you want to rotate the Bitmap
    // matrix.postRotate(45);

    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
        height, matrix, true);

    // make a Drawable from Bitmap to allow to set the Bitmap
    // to the ImageView, ImageButton or what ever
    return new BitmapDrawable(resizedBitmap);

  }

}// end class AppUtils

Drawable.createFromStream and URL connection

  
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.drawable.Drawable;

public class NetworkUtil {

  public static Drawable getDrawableFromUrl(String url, String src_name) {
    try {
      return Drawable.createFromStream(
          ((InputStream) new URL(url).getContent()), src_name);
    } catch (MalformedURLException e) {
      e.printStackTrace();
      return null;
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
  }
}

Drawable Manager with Thread

  
//package com.sjtu.is.mobili.utils;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

public class DrawableManager {
    private final Map<String, Drawable> drawableMap;

    public DrawableManager() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");
            drawableMap.put(urlString, drawable);
            //Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
            //        + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
            //        + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
        if (drawableMap.containsKey(urlString)) {
            imageView.setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
              if (message.obj==null){
                Log.d("imageDownder", "image is null");
              }else{
                imageView.setImageDrawable((Drawable) message.obj);
              }
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }

}

get Drawable From Web Operation

  
//package com.filmatchs.utils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.util.Log;

/**
 * TODO: class ini harus dikembangkan menjadi
 * 
 * @author khalifavi
 * 
 */
public class ImageManager {
  public static final String LOG_TAG = "DrawableManager";

  /**
   * get Drawable from a URL request
   * @param url
   * @return Drawable
   */
  public static Drawable getDrawableFromWebOperation(String url) {
    try {
      InputStream is = (InputStream) new URL(url).getContent();
      Drawable d = Drawable.createFromStream(is, url);
      return d;
    } catch (Exception e) {
      Log.e(LOG_TAG, e.getMessage());
      return null;
    }
  }

  /**
   * get Bitmap from a URL request
   * @param url
   * @return Bitmap
   */
  public static Bitmap getBitmapFromWebOperation(String url) {
    try {
      InputStream is = (InputStream) new URL(url).getContent();
      Bitmap b = BitmapFactory.decodeStream(is);
      return b;
    } catch (Exception e) {
      Log.e(LOG_TAG, e.getMessage());
      return null;
    }
  }

  /**
   * get ByteArray from a URL request 
   * @param url
   * @return ByteArray
   */
  public static byte[] getByteArrayFromWebOperation(String url) {
    try {
      InputStream is = (InputStream) new URL(url).getContent();
      // this dynamically extends to take the bytes you read
      ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();

      // this is storage overwritten on each iteration with bytes
      byte[] buffer = new byte[1024];

      // we need to know how may bytes were read to write them to the
      // byteBuffer
      int len = 0;
      while ((len = is.read(buffer)) != -1) {
        byteBuffer.write(buffer, 0, len);
      }

      // and then we can return your byte array.
      return byteBuffer.toByteArray();
    } catch (Exception e) {
      Log.e(LOG_TAG, e.getMessage());
      return null;
    }
  }

  /**
   * Resize a Bitmap
   * @param bitmap
   * @param width
   * @param height
   * @return Bitmap resized bitmap
   */
  public static Bitmap getResizedBitmap(Bitmap bitmap, int width, int height) {

    final int bitmapWidth = bitmap.getWidth();
    final int bitmapHeight = bitmap.getHeight();

    final float scale = Math.min((float) width / (float) bitmapWidth,
        (float) height / (float) bitmapHeight);

    final int scaledWidth = (int) (bitmapWidth * scale);
    final int scaledHeight = (int) (bitmapHeight * scale);

    final Bitmap decored = Bitmap.createScaledBitmap(bitmap, scaledWidth,
        scaledHeight, true);

    return decored;
  }

}

Center a Drawable

  
import android.graphics.drawable.Drawable;

 class Utilities {
  static void centerAround(int x, int y, Drawable d) {
    int w = d.getIntrinsicWidth();
    int h = d.getIntrinsicHeight();
    int left = x - w / 2;
    int top = y - h / 2;
    int right = left + w;
    int bottom = top + h;
    d.setBounds(left, top, right, bottom);
  }

}

Rotate around Center Point

   
package app.test;

import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class Test extends Activity implements OnClickListener {

  ImageView chosenImageView;
  Button choosePicture;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView);
    choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton);

    choosePicture.setOnClickListener(this);
  }

  public void onClick(View v) {
    Intent choosePictureIntent = new Intent(Intent.ACTION_PICK,
        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(choosePictureIntent, 0);
  }

  protected void onActivityResult(int requestCode, int resultCode,
      Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (resultCode == RESULT_OK) {
      Uri imageFileUri = intent.getData();

      Display currentDisplay = getWindowManager().getDefaultDisplay();
      int dw = currentDisplay.getWidth();
      int dh = currentDisplay.getHeight() / 2 - 100;

      try {
        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
        bmpFactoryOptions.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                imageFileUri), null, bmpFactoryOptions);

        bmpFactoryOptions.inSampleSize = 2;
        bmpFactoryOptions.inJustDecodeBounds = false;
        bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                imageFileUri), null, bmpFactoryOptions);
        Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
            .getHeight(), bmp.getConfig());
        Canvas canvas = new Canvas(alteredBitmap);
        Paint paint = new Paint();

        Matrix matrix = new Matrix();
        // Rotate around Center Point
        matrix.setRotate(15,bmp.getWidth()/2,bmp.getHeight()/2);

        canvas.drawBitmap(bmp, matrix, paint);

        ImageView alteredImageView = (ImageView) this.findViewById(R.id.AlteredImageView);
        alteredImageView.setImageBitmap(alteredBitmap);

        chosenImageView.setImageBitmap(bmp);

      } catch (Exception e) {
        Log.v("ERROR", e.toString());
      }
    }
  }
}

//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"
    >
<Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/>

<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView>
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView>
</LinearLayout>