Skip to main content

Display Image from specific folder with rounded shape thumbnail and View it and flip it(Complete gallary code)

Hi friends ,This is complete post, about how to display Image form specific folder.
We have added some features on it like onClick view it and flip it on touch event,display next previous image on touch and flip.There is one more option also important has been added that onLongClick display option and this option menu has two options First one is for Share and second one is for Delete.When we click on Share option it display list that where do you want to share image i.e. facebook,twitter,Blutooth etc. And When you click on Delete option selected image will be delete.Actually its been good journey of developing this application.
Now try to understand following codes that i have used in my application for work done.
       I have declared three package one for touch, second for utilities and third for implementation of all codes.
Now have look on First(Touch package)
EclairMotionEvent.java
package com.dilip.android.ui.touch;



import android.view.MotionEvent;



public class EclairMotionEvent extends WrapMotionEvent {



    protected EclairMotionEvent(MotionEvent event) {
        super(event);
    }



    public float getX(int pointerIndex) {
        return event.getX(pointerIndex);
    }



    public float getY(int pointerIndex) {
        return event.getY(pointerIndex);
    }



    public int getPointerCount() {
        return event.getPointerCount();
    }



    public int getPointerId(int pointerIndex) {
        return event.getPointerId(pointerIndex);
    }
}
TouchActivity.java
package com.dilip.android.ui.touch;



import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;



public abstract class TouchActivity extends Activity {
    private static final String TAG = "Touch";
    // These matrices will be used to move and zoom image
    protected Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();



    // We can be in one of these 3 states
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    int mode = NONE;



    // Remember some things for zooming
    PointF start = new PointF();
    PointF refLineStart = null;
    PointF refLineEnd = null;
    PointF prevLineStart = null;
    PointF prevLineEnd = null;
    PointF newStart = new PointF();
    PointF newEnd = new PointF();
    float oldAngle = 0f;



    PointF mid = new PointF();
    float oldDist = 1f;
    Float mRotateAngle = 0f;
    float scaleFactor = 0f;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(getContentView());
        // ImageView view = getImageView();
        // view.setOnTouchListener(this);



        // ...
        // Work around a Cupcake bug
        matrix.setTranslate(1f, 1f);
        // view.setImageMatrix(matrix);
    }



    public abstract float getMinZoomScale();



    public abstract void resetImage(ImageView iv, Drawable draw);



    public boolean onTouchEvented(View v, MotionEvent rawEvent) {



        WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
        // ...
        ImageView view = (ImageView) v;



        // Dump touch event to log
        dumpEvent(event);



        // Handle touch events here...
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            Log.d(TAG, "mode=DRAG");
            mode = DRAG;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            Log.d(TAG, "oldDist=" + oldDist);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
                Log.d(TAG, "mode=ZOOM");



                // set the old line if first attempt
                refLineStart = new PointF();
                refLineEnd = new PointF();
                refLineStart.set(event.getX(0), event.getY(0));
                refLineEnd.set(event.getX(1), event.getY(1));
                prevLineStart = new PointF();
                prevLineEnd = new PointF();
                prevLineStart.set(event.getX(0), event.getY(0));
                prevLineEnd.set(event.getX(1), event.getY(1));
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            Log.d(TAG, "mode=NONE");
            refLineStart = null;
            refLineEnd = null;
            mRotateAngle = 0f;



            boolean isScaleChanged = true;
            float[] values = new float[9];
            view.getImageMatrix().getValues(values);
            if (values[0] <= getMinZoomScale()) {
                resetImage(view, view.getDrawable());
                isScaleChanged = false;
            }



            Rect rect = new Rect();
            view.getDrawingRect(rect);
            Log.d("ImageView", "Drawing Rect: " + rect.top + "," + rect.right
                    + "," + rect.bottom + "," + rect.left);



            float[] point = new float[2];



            // for top and left
            point[0] = rect.left;
            point[1] = rect.top;
            float[] topleft = new float[2];
            view.getImageMatrix().mapPoints(topleft, point); // topleft image
                                                                // point after
                                                                // applying
                                                                // matrix



            point[0] = view.getDrawable().getIntrinsicWidth();
            point[1] = view.getDrawable().getIntrinsicHeight();
            float[] bottomright = new float[2];
            view.getImageMatrix().mapPoints(bottomright, point); // bottomright
                                                                    // image
                                                                    // point
                                                                    // after
                                                                    // applying
                                                                    // matrix



            // get orientation
            Display display = ((WindowManager) getSystemService(WINDOW_SERVICE))
                    .getDefaultDisplay();
            int rotation = display.getRotation();



            int orientation = 0;
            if (rotation == Surface.ROTATION_0
                    || rotation == Surface.ROTATION_180)
                orientation = 0;
            else
                orientation = 1;



            boolean direction = true;



            float width = bottomright[0] - topleft[0];
            float height = bottomright[1] - topleft[1];



            if ((width > rect.right && height > rect.bottom))
                direction = true;
            else
                direction = false;



            // snap to topright
            if (topleft[0] > rect.left && bottomright[0] > rect.right
                    && isScaleChanged && direction) {
                matrix.postTranslate(-topleft[0], 0);
            } else if (bottomright[0] < rect.right && topleft[0] < rect.left
                    && isScaleChanged && direction) {
                matrix.postTranslate(rect.right - bottomright[0], 0);
            } else if (topleft[0] > rect.left && bottomright[0] > rect.right
                    && isScaleChanged && !direction) {
                matrix.postTranslate(-(bottomright[0] - rect.right), 0);
            } else if (bottomright[0] < rect.right && topleft[0] < rect.left
                    && isScaleChanged && !direction) {
                matrix.postTranslate(-(topleft[0] - rect.left), 0);
            }



            if (bottomright[1] > rect.bottom && topleft[1] > rect.top
                    && isScaleChanged && direction) {
                matrix.postTranslate(0, -topleft[1]);
            } else if (bottomright[1] < rect.bottom && topleft[1] < rect.top
                    && isScaleChanged && direction) {
                matrix.postTranslate(0, rect.bottom - bottomright[1]);
            } else if (bottomright[1] > rect.bottom && topleft[1] > rect.top
                    && isScaleChanged && !direction) {
                matrix.postTranslate(0, -(bottomright[1] - rect.bottom));
            } else if (bottomright[1] < rect.bottom && topleft[1] < rect.top
                    && isScaleChanged && !direction) {
                matrix.postTranslate(0, -(topleft[1] - rect.top));
            }



            Log.d("ImageView", "Map points source " + point[0] + "," + point[1]
                    + " to topleft:" + topleft[0] + "," + topleft[1]
                    + " and bottomright:" + bottomright[0] + ","
                    + bottomright[1]);



            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG) {
                // ...
                matrix.set(savedMatrix);
                matrix.postTranslate(event.getX() - start.x, event.getY()
                        - start.y);
            } else if (mode == ZOOM) {
                float newDist = spacing(event);
                Log.d(TAG, "newDist=" + newDist);
                if (newDist > 10f) {
                    matrix.set(savedMatrix);
                    float scale = newDist / oldDist;



                    Log.v("Scaling", "Scale: " + scale);



                    Matrix test = new Matrix(matrix);



                    // test scale matrix
                    test.postScale(scale, scale, mid.x, mid.y);
                    float[] svalues = new float[9];
                    test.getValues(svalues);



                    // if(svalues[0]>=getMinZoomScale())
                    matrix.postScale(scale, scale, mid.x, mid.y);
                    // else
                    // matrix.setScale(getMinZoomScale(), getMinZoomScale(),
                    // mid.x, mid.y);



                    // get the latest line
                    newStart.set(event.getX(0), event.getY(0));
                    newEnd.set(event.getX(1), event.getY(1));



                    float angle = new Float(angleBetweenLinesInRadians(
                            prevLineStart, prevLineEnd, newStart, newEnd))
                            .floatValue();



                    // calculate the angle difference and do rotation



                    mRotateAngle = mRotateAngle + angle;



                    // matrix.postRotate( mRotateAngle ,mid.x, mid.y );
                    // record the old line value
                    prevLineStart.set(event.getX(0), event.getY(0));
                    prevLineEnd.set(event.getX(1), event.getY(1));
                }



            }
            break;
        }



        Log.v("Matrix", "scale matrix: " + matrix);



        view.setImageMatrix(matrix);



        System.gc();



        return true; // indicate event was handled
    }



    public double angleBetweenLinesInRadians(PointF line1Start,
            PointF line1End, PointF line2Start, PointF line2End) {



        float a = line1End.x - line1Start.x;
        float b = line1End.y - line1Start.y;
        float c = line2End.x - line2Start.x;
        float d = line2End.y - line2Start.y;



        float line1Slope = (line1End.y - line1Start.y)
                / (line1End.x - line1Start.x);
        float line2Slope = (line2End.y - line2Start.y)
                / (line2End.x - line2Start.x);



        double subf = ((a * c) + (b * d))
                / ((Math.sqrt(a * a + b * b)) * (Math.sqrt(c * c + d * d)));



        subf = subf > 1 ? 1 : subf;
        subf = subf < -1 ? -1 : subf;
        double degs = Math.acos(subf);



        double result = (line2Slope > line1Slope) ? degs * 180 / 3.142
                : -degs * 180 / 3.142;



        return result;
    }



    /** Show an event in the LogCat view, for debugging */
    private void dumpEvent(WrapMotionEvent event) {
        // ...
        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
        StringBuilder sb = new StringBuilder();
        int action = event.getAction();
        int actionCode = action & MotionEvent.ACTION_MASK;
        sb.append("event ACTION_").append(names[actionCode]);
        if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                || actionCode == MotionEvent.ACTION_POINTER_UP) {
            sb.append("(pid ").append(
                    action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
            sb.append(")");
        }
        sb.append("[");
        for (int i = 0; i < event.getPointerCount(); i++) {
            sb.append("#").append(i);
            sb.append("(pid ").append(event.getPointerId(i));
            sb.append(")=").append((int) event.getX(i));
            sb.append(",").append((int) event.getY(i));
            if (i + 1 < event.getPointerCount())
                sb.append(";");
        }
        sb.append("]");
        Log.d(TAG, sb.toString());
    }



    /** Determine the space between the first two fingers */
    private float spacing(WrapMotionEvent event) {
        // ...
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }



    /** Calculate the mid point of the first two fingers */
    private void midPoint(PointF point, WrapMotionEvent event) {
        // ...
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
}
WrapMotionEvent.java
package com.dilip.android.ui.touch;



import android.view.MotionEvent;



public class WrapMotionEvent {
    protected MotionEvent event;



    protected WrapMotionEvent(MotionEvent event) {
        this.event = event;
    }



    static public WrapMotionEvent wrap(MotionEvent event) {
        try {
            return new EclairMotionEvent(event);
        } catch (VerifyError e) {
            return new WrapMotionEvent(event);
        }
    }



    public int getAction() {
        return event.getAction();
    }



    public float getX() {
        return event.getX();
    }



    public float getX(int pointerIndex) {
        verifyPointerIndex(pointerIndex);
        return getX();
    }



    public float getY() {
        return event.getY();
    }



    public float getY(int pointerIndex) {
        verifyPointerIndex(pointerIndex);
        return getY();
    }



    public int getPointerCount() {
        return 1;
    }



    public int getPointerId(int pointerIndex) {
        verifyPointerIndex(pointerIndex);
        return 0;
    }



    private void verifyPointerIndex(int pointerIndex) {
        if (pointerIndex > 0) {
            throw new IllegalArgumentException(
                    "Invalid pointer index for Donut/Cupcake");
        }
    }



}
Now have a look on second utilities package.
FileUtils.java
package com.dilip.android.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;



import android.util.Log;



public class FileUtils {



    public void saveArray(String filename, List<String> output_field) {
        try {
            FileOutputStream fos = new FileOutputStream(filename);
            GZIPOutputStream gzos = new GZIPOutputStream(fos);
            ObjectOutputStream out = new ObjectOutputStream(gzos);
            out.writeObject(output_field);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.getStackTrace();
        }
    }



    @SuppressWarnings("unchecked")
    public List<String> loadArray(String filename) {
        try {
            FileInputStream fis = new FileInputStream(filename);
            GZIPInputStream gzis = new GZIPInputStream(fis);
            ObjectInputStream in = new ObjectInputStream(gzis);
            List<String> read_field = (List<String>) in.readObject();
            in.close();
            return read_field;
        } catch (Exception e) {
            e.getStackTrace();
        }
        return null;
    }



    public File[] listFilesAsArray(File directory, FilenameFilter[] filter,
            int recurse) {
        Collection<File> files = listFiles(directory, filter, recurse);



        File[] arr = new File[files.size()];
        return files.toArray(arr);
    }



    public Collection<File> listFiles(File directory, FilenameFilter[] filter,
            int recurse) {



        Vector<File> files = new Vector<File>();



        File[] entries = directory.listFiles();



        if (entries != null) {
            for (File entry : entries) {
                for (FilenameFilter filefilter : filter) {
                    if (filter == null
                            || filefilter.accept(directory, entry.getName())) {
                        files.add(entry);
                        Log.v("HelloActivity", "Added: " + entry.getName());
                    }
                }
                if ((recurse <= -1) || (recurse > 0 && entry.isDirectory())) {
                    recurse--;
                    files.addAll(listFiles(entry, filter, recurse));
                    recurse++;
                }
            }
        }
        return files;
    }
}
Geometry.java
package com.dilip.android.util;



/*



 *
 * This code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA  02111-1307, USA.
 */






public final class Geometry {
    /**
     * Return true if c is between a and b.
     */
    private static boolean isBetween(int a, int b, int c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }



    /**
     * Return true if c is between a and b.
     */
    private static boolean isBetween(double a, double b, double c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }



    /**
     * Check if two double precision numbers are "equal", i.e. close enough to a
     * given limit.
     *
     * @param a
     *            First number to check
     * @param b
     *            Second number to check
     * @param limit
     *            The definition of "equal".
     * @return True if the twho numbers are "equal", false otherwise
     */
    private static boolean equals(double a, double b, double limit) {
        return Math.abs(a - b) < limit;
    }



    /**
     * Check if two double precision numbers are "equal", i.e. close enough to a
     * prespecified limit.
     *
     * @param a
     *            First number to check
     * @param b
     *            Second number to check
     * @return True if the twho numbers are "equal", false otherwise
     */
    private static boolean equals(double a, double b) {
        return equals(a, b, 1.0e-5);
    }



    /**
     * Return smallest of four numbers.
     *
     * @param a
     *            First number to find smallest among.
     * @param b
     *            Second number to find smallest among.
     * @param c
     *            Third number to find smallest among.
     * @param d
     *            Fourth number to find smallest among.
     * @return Smallest of a, b, c and d.
     */
    private static double min(double a, double b, double c, double d) {
        return Math.min(Math.min(a, b), Math.min(c, d));
    }



    /**
     * Return largest of four numbers.
     *
     * @param a
     *            First number to find largest among.
     * @param b
     *            Second number to find largest among.
     * @param c
     *            Third number to find largest among.
     * @param d
     *            Fourth number to find largest among.
     * @return Largest of a, b, c and d.
     */
    private static double max(double a, double b, double c, double d) {
        return Math.max(Math.max(a, b), Math.max(c, d));
    }



    /**
     * Check if a specified point is inside a specified rectangle.
     *
     * @param x0
     *            , y0, x1, y1 Upper left and lower right corner of rectangle
     *            (inclusive)
     * @param x
     *            ,y Point to check.
     * @return True if the point is inside the rectangle, false otherwise.
     */
    public static boolean isPointInsideRectangle(int x0, int y0, int x1,
            int y1, int x, int y) {
        return x >= x0 && x < x1 && y >= y0 && y < y1;
    }



    /**
     * Check if a given point is inside a given (complex) polygon.
     *
     * @param x
     *            , y Polygon.
     * @param pointX
     *            , pointY Point to check.
     * @return True if the given point is inside the polygon, false otherwise.
     */
    public static boolean isPointInsidePolygon(double[] x, double[] y,
            double pointX, double pointY) {
        boolean isInside = false;
        int nPoints = x.length;



        int j = 0;
        for (int i = 0; i < nPoints; i++) {
            j++;
            if (j == nPoints)
                j = 0;



            if (y[i] < pointY && y[j] >= pointY || y[j] < pointY
                    && y[i] >= pointY) {
                if (x[i] + (pointY - y[i]) / (y[j] - y[i]) * (x[j] - x[i]) < pointX) {
                    isInside = !isInside;
                }
            }
        }



        return isInside;
    }



    /**
     * Check if a given point is inside a given polygon. Integer domain.
     *
     * @param x
     *            , y Polygon.
     * @param pointX
     *            , pointY Point to check.
     * @return True if the given point is inside the polygon, false otherwise.
     */
    public static boolean isPointInsidePolygon(int[] x, int[] y, int pointX,
            int pointY) {
        boolean isInside = false;
        int nPoints = x.length;



        int j = 0;
        for (int i = 0; i < nPoints; i++) {
            j++;
            if (j == nPoints)
                j = 0;



            if (y[i] < pointY && y[j] >= pointY || y[j] < pointY
                    && y[i] >= pointY) {
                if (x[i] + (double) (pointY - y[i]) / (double) (y[j] - y[i])
                        * (x[j] - x[i]) < pointX) {
                    isInside = !isInside;
                }
            }
        }



        return isInside;
    }



    /**
     * Find the point on the line p0,p1 [x,y,z] a given fraction from p0.
     * Fraction of 0.0 whould give back p0, 1.0 give back p1, 0.5 returns
     * midpoint of line p0,p1 and so on. F raction can be >1 and it can be
     * negative to return any point on the line specified by p0,p1.
     *
     * @param p0
     *            First coordinale of line [x,y,z].
     * @param p0
     *            Second coordinale of line [x,y,z].
     * @param fractionFromP0
     *            Point we are looking for coordinates of
     * @param p
     *            Coordinate of point we are looking for
     */
    public static double[] computePointOnLine(double[] p0, double[] p1,
            double fractionFromP0) {
        double[] p = new double[3];



        p[0] = p0[0] + fractionFromP0 * (p1[0] - p0[0]);
        p[1] = p0[1] + fractionFromP0 * (p1[1] - p0[1]);
        p[2] = p0[2] + fractionFromP0 * (p1[2] - p0[2]);



        return p;
    }



    /**
     * Find the point on the line defined by x0,y0,x1,y1 a given fraction from
     * x0,y0. 2D version of method above..
     *
     * @param x0
     *            , y0 First point defining the line
     * @param x1
     *            , y1 Second point defining the line
     * @param fractionFrom0
     *            Distance from (x0,y0)
     * @return x, y Coordinate of point we are looking for
     */
    public static double[] computePointOnLine(double x0, double y0, double x1,
            double y1, double fractionFrom0) {
        double[] p0 = { x0, y0, 0.0 };
        double[] p1 = { x1, y1, 0.0 };



        double[] p = Geometry.computePointOnLine(p0, p1, fractionFrom0);



        double[] r = { p[0], p[1] };
        return r;
    }



    /**
     * Extend a given line segment to a specified length.
     *
     * @param p0
     *            , p1 Line segment to extend [x,y,z].
     * @param toLength
     *            Length of new line segment.
     * @param anchor
     *            Specifies the fixed point during extension. If anchor is 0.0,
     *            p0 is fixed and p1 is adjusted. If anchor is 1.0, p1 is fixed
     *            and p0 is adjusted. If anchor is 0.5, the line is adjusted
     *            equally in each direction and so on.
     */
    public static void extendLine(double[] p0, double[] p1, double toLength,
            double anchor) {
        double[] p = Geometry.computePointOnLine(p0, p1, anchor);



        double length0 = toLength * anchor;
        double length1 = toLength * (1.0 - anchor);



        Geometry.extendLine(p, p0, length0);
        Geometry.extendLine(p, p1, length1);
    }



    /**
     * Extend a given line segment to a given length and holding the first point
     * of the line as fixed.
     *
     * @param p0
     *            , p1 Line segment to extend. p0 is fixed during extension
     * @param length
     *            Length of new line segment.
     */
    public static void extendLine(double[] p0, double[] p1, double toLength) {
        double oldLength = Geometry.length(p0, p1);
        double lengthFraction = oldLength != 0.0 ? toLength / oldLength : 0.0;



        p1[0] = p0[0] + (p1[0] - p0[0]) * lengthFraction;
        p1[1] = p0[1] + (p1[1] - p0[1]) * lengthFraction;
        p1[2] = p0[2] + (p1[2] - p0[2]) * lengthFraction;
    }



    /**
     * Return the length of a vector.
     *
     * @param v
     *            Vector to compute length of [x,y,z].
     * @return Length of vector.
     */
    public static double length(double[] v) {
        return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
    }



    /**
     * Compute distance between two points.
     *
     * @param p0
     *            , p1 Points to compute distance between [x,y,z].
     * @return Distance between points.
     */
    public static double length(double[] p0, double[] p1) {
        double[] v = Geometry.createVector(p0, p1);
        return length(v);
    }



    /**
     * Compute the length of the line from (x0,y0) to (x1,y1)
     *
     * @param x0
     *            , y0 First line end point.
     * @param x1
     *            , y1 Second line end point.
     * @return Length of line from (x0,y0) to (x1,y1).
     */
    public static double length(int x0, int y0, int x1, int y1) {
        return Geometry.length((double) x0, (double) y0, (double) x1,
                (double) y1);
    }



    /**
     * Compute the length of the line from (x0,y0) to (x1,y1)
     *
     * @param x0
     *            , y0 First line end point.
     * @param x1
     *            , y1 Second line end point.
     * @return Length of line from (x0,y0) to (x1,y1).
     */
    public static double length(double x0, double y0, double x1, double y1) {
        double dx = x1 - x0;
        double dy = y1 - y0;



        return Math.sqrt(dx * dx + dy * dy);
    }



    /**
     * Compute the length of a polyline.
     *
     * @param x
     *            , y Arrays of x,y coordinates
     * @param nPoints
     *            Number of elements in the above.
     * @param isClosed
     *            True if this is a closed polygon, false otherwise
     * @return Length of polyline defined by x, y and nPoints.
     */
    public static double length(int[] x, int[] y, boolean isClosed) {
        double length = 0.0;



        int nPoints = x.length;
        for (int i = 0; i < nPoints - 1; i++)
            length += Geometry.length(x[i], y[i], x[i + 1], y[i + 1]);



        // Add last leg if this is a polygon
        if (isClosed && nPoints > 1)
            length += Geometry.length(x[nPoints - 1], y[nPoints - 1], x[0],
                    y[0]);



        return length;
    }



    /**
     * Return distance bwetween the line defined by (x0,y0) and (x1,y1) and the
     * point (x,y). Ref:
     * http://astronomy.swin.edu.au/pbourke/geometry/pointline/ The 3D case
     * should be similar.
     *
     * @param x0
     *            , y0 First point of line.
     * @param x1
     *            , y1 Second point of line.
     * @param x
     *            , y, Point to consider.
     * @return Distance from x,y down to the (extended) line defined by x0, y0,
     *         x1, y1.
     */
    public static double distance(int x0, int y0, int x1, int y1, int x, int y) {
        // If x0,y0,x1,y1 is same point, we return distance to that point
        double length = Geometry.length(x0, y0, x1, y1);
        if (length == 0.0)
            return Geometry.length(x0, y0, x, y);



        // If u is [0,1] then (xp,yp) is on the line segment (x0,y0),(x1,y1).
        double u = ((x - x0) * (x1 - x0) + (y - y0) * (y1 - y0))
                / (length * length);



        // This is the intersection point of the normal.
        // TODO: Might consider returning this as well.
        double xp = x0 + u * (x1 - x0);
        double yp = y0 + u * (y1 - y0);



        length = Geometry.length(xp, yp, x, y);
        return length;
    }



    /**
     * Find the angle between twree points. P0 is center point
     *
     * @param p0
     *            , p1, p2 Three points finding angle between [x,y,z].
     * @return Angle (in radians) between given points.
     */
    public static double computeAngle(double[] p0, double[] p1, double[] p2) {
        double[] v0 = Geometry.createVector(p0, p1);
        double[] v1 = Geometry.createVector(p0, p2);



        double dotProduct = Geometry.computeDotProduct(v0, v1);



        double length1 = Geometry.length(v0);
        double length2 = Geometry.length(v1);



        double denominator = length1 * length2;



        double product = denominator != 0.0 ? dotProduct / denominator : 0.0;



        double angle = Math.acos(product);



        return angle;
    }



    /**
     * Compute the dot product (a scalar) between two vectors.
     *
     * @param v0
     *            , v1 Vectors to compute dot product between [x,y,z].
     * @return Dot product of given vectors.
     */
    public static double computeDotProduct(double[] v0, double[] v1) {
        return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
    }



    /**
     * Compute the cross product (a vector) of two vectors.
     *
     * @param v0
     *            , v1 Vectors to compute cross product between [x,y,z].
     * @param crossProduct
     *            Cross product of specified vectors [x,y,z].
     */
    public static double[] computeCrossProduct(double[] v0, double[] v1) {
        double crossProduct[] = new double[3];



        crossProduct[0] = v0[1] * v1[2] - v0[2] * v1[1];
        crossProduct[1] = v0[2] * v1[0] - v0[0] * v1[2];
        crossProduct[2] = v0[0] * v1[1] - v0[1] * v1[0];



        return crossProduct;
    }



    /**
     * Construct the vector specified by two points.
     *
     * @param p0
     *            , p1 Points the construct vector between [x,y,z].
     * @return v Vector from p0 to p1 [x,y,z].
     */
    public static double[] createVector(double[] p0, double[] p1) {
        double v[] = { p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2] };
        return v;
    }



    /**
     * Check if two points are on the same side of a given line. Algorithm from
     * Sedgewick page 350.
     *
     * @param x0
     *            , y0, x1, y1 The line.
     * @param px0
     *            , py0 First point.
     * @param px1
     *            , py1 Second point.
     * @return <0 if points on opposite sides. =0 if one of the points is
     *         exactly on the line >0 if points on same side.
     */
    private static int sameSide(double x0, double y0, double x1, double y1,
            double px0, double py0, double px1, double py1) {
        int sameSide = 0;



        double dx = x1 - x0;
        double dy = y1 - y0;
        double dx1 = px0 - x0;
        double dy1 = py0 - y0;
        double dx2 = px1 - x1;
        double dy2 = py1 - y1;



        // Cross product of the vector from the endpoint of the line to the
        // point
        double c1 = dx * dy1 - dy * dx1;
        double c2 = dx * dy2 - dy * dx2;



        if (c1 != 0 && c2 != 0)
            sameSide = c1 < 0 != c2 < 0 ? -1 : 1;
        else if (dx == 0 && dx1 == 0 && dx2 == 0)
            sameSide = !isBetween(y0, y1, py0) && !isBetween(y0, y1, py1) ? 1
                    : 0;
        else if (dy == 0 && dy1 == 0 && dy2 == 0)
            sameSide = !isBetween(x0, x1, px0) && !isBetween(x0, x1, px1) ? 1
                    : 0;



        return sameSide;
    }



    /**
     * Check if two points are on the same side of a given line. Integer domain.
     *
     * @param x0
     *            , y0, x1, y1 The line.
     * @param px0
     *            , py0 First point.
     * @param px1
     *            , py1 Second point.
     * @return <0 if points on opposite sides. =0 if one of the points is
     *         exactly on the line >0 if points on same side.
     */
    private static int sameSide(int x0, int y0, int x1, int y1, int px0,
            int py0, int px1, int py1) {
        return sameSide((double) x0, (double) y0, (double) x1, (double) y1,
                (double) px0, (double) py0, (double) px1, (double) py1);
    }



    /**
     * Check if two line segments intersects. Integer domain.
     *
     * @param x0
     *            , y0, x1, y1 End points of first line to check.
     * @param x2
     *            , yy, x3, y3 End points of second line to check.
     * @return True if the two lines intersects.
     */
    public static boolean isLineIntersectingLine(int x0, int y0, int x1,
            int y1, int x2, int y2, int x3, int y3) {
        int s1 = Geometry.sameSide(x0, y0, x1, y1, x2, y2, x3, y3);
        int s2 = Geometry.sameSide(x2, y2, x3, y3, x0, y0, x1, y1);



        return s1 <= 0 && s2 <= 0;
    }



    /**
     * Check if a specified line intersects a specified rectangle. Integer
     * domain.
     *
     * @param lx0
     *            , ly0 1st end point of line
     * @param ly1
     *            , ly1 2nd end point of line
     * @param x0
     *            , y0, x1, y1 Upper left and lower right corner of rectangle
     *            (inclusive).
     * @return True if the line intersects the rectangle, false otherwise.
     */
    public static boolean isLineIntersectingRectangle(int lx0, int ly0,
            int lx1, int ly1, int x0, int y0, int x1, int y1) {
        // Is one of the line endpoints inside the rectangle
        if (Geometry.isPointInsideRectangle(x0, y0, x1, y1, lx0, ly0)
                || Geometry.isPointInsideRectangle(x0, y0, x1, y1, lx1, ly1))
            return true;



        // If it intersects it goes through. Need to check three sides only.



        // Check against top rectangle line
        if (Geometry.isLineIntersectingLine(lx0, ly0, lx1, ly1, x0, y0, x1, y0))
            return true;



        // Check against left rectangle line
        if (Geometry.isLineIntersectingLine(lx0, ly0, lx1, ly1, x0, y0, x0, y1))
            return true;



        // Check against bottom rectangle line
        if (Geometry.isLineIntersectingLine(lx0, ly0, lx1, ly1, x0, y1, x1, y1))
            return true;



        return false;
    }



    /**
     * Check if a specified polyline intersects a specified rectangle. Integer
     * domain.
     *
     * @param x
     *            , y Polyline to check.
     * @param x0
     *            , y0, x1, y1 Upper left and lower left corner of rectangle
     *            (inclusive).
     * @return True if the polyline intersects the rectangle, false otherwise.
     */
    public static boolean isPolylineIntersectingRectangle(int[] x, int[] y,
            int x0, int y0, int x1, int y1) {
        if (x.length == 0)
            return false;



        if (Geometry.isPointInsideRectangle(x[0], y[0], x0, y0, x1, y1))
            return true;



        else if (x.length == 1)
            return false;



        for (int i = 1; i < x.length; i++) {
            if (x[i - 1] != x[i] || y[i - 1] != y[i])
                if (Geometry.isLineIntersectingRectangle(x[i - 1], y[i - 1],
                        x[i], y[i], x0, y0, x1, y1))
                    return true;
        }



        return false;
    }



    /**
     * Check if a specified polygon intersects a specified rectangle. Integer
     * domain.
     *
     * @param x
     *            X coordinates of polyline.
     * @param y
     *            Y coordinates of polyline.
     * @param x0
     *            X of upper left corner of rectangle.
     * @param y0
     *            Y of upper left corner of rectangle.
     * @param x1
     *            X of lower right corner of rectangle.
     * @param y1
     *            Y of lower right corner of rectangle.
     * @return True if the polyline intersects the rectangle, false otherwise.
     */
    public static boolean isPolygonIntersectingRectangle(int[] x, int[] y,
            int x0, int y0, int x1, int y1) {
        int n = x.length;



        if (n == 0)
            return false;



        if (n == 1)
            return Geometry.isPointInsideRectangle(x0, y0, x1, y1, x[0], y[0]);



        //
        // If the polyline constituting the polygon intersects the rectangle
        // the polygon does too.
        //
        if (Geometry.isPolylineIntersectingRectangle(x, y, x0, y0, x1, y1))
            return true;



        // Check last leg as well
        if (Geometry.isLineIntersectingRectangle(x[n - 2], y[n - 2], x[n - 1],
                y[n - 1], x0, y0, x1, y1))
            return true;



        //
        // The rectangle and polygon are now completely including each other
        // or separate.
        //
        if (Geometry.isPointInsidePolygon(x, y, x0, y0)
                || Geometry.isPointInsideRectangle(x0, y0, x1, y1, x[0], y[0]))
            return true;



        // Separate
        return false;
    }



    /**
     * Compute the area of the specfied polygon.
     *
     * @param x
     *            X coordinates of polygon.
     * @param y
     *            Y coordinates of polygon.
     * @return Area of specified polygon.
     */
    public static double computePolygonArea(double[] x, double[] y) {
        int n = x.length;



        double area = 0.0;
        for (int i = 0; i < n - 1; i++)
            area += (x[i] * y[i + 1]) - (x[i + 1] * y[i]);
        area += (x[n - 1] * y[0]) - (x[0] * y[n - 1]);



        area *= 0.5;



        return area;
    }



    /**
     * Compute the area of the specfied polygon.
     *
     * @param xy
     *            Geometry of polygon [x,y,...]
     * @return Area of specified polygon.
     */
    public static double computePolygonArea(double[] xy) {
        int n = xy.length;



        double area = 0.0;
        for (int i = 0; i < n - 2; i += 2)
            area += (xy[i] * xy[i + 3]) - (xy[i + 2] * xy[i + 1]);
        area += (xy[xy.length - 2] * xy[1]) - (xy[0] * xy[xy.length - 1]);



        area *= 0.5;



        return area;
    }



    /**
     * Compute centorid (center of gravity) of specified polygon.
     *
     * @param x
     *            X coordinates of polygon.
     * @param y
     *            Y coordinates of polygon.
     * @return Centroid [x,y] of specified polygon.
     */
    public static double[] computePolygonCentroid(double[] x, double[] y) {
        double cx = 0.0;
        double cy = 0.0;



        int n = x.length;
        for (int i = 0; i < n - 1; i++) {
            double a = x[i] * y[i + 1] - x[i + 1] * y[i];
            cx += (x[i] + x[i + 1]) * a;
            cy += (y[i] + y[i + 1]) * a;
        }
        double a = x[n - 1] * y[0] - x[0] * y[n - 1];
        cx += (x[n - 1] + x[0]) * a;
        cy += (y[n - 1] + y[0]) * a;



        double area = Geometry.computePolygonArea(x, y);



        cx /= 6 * area;
        cy /= 6 * area;



        return new double[] { cx, cy };
    }



    /**
     * Find the 3D extent of a polyline.
     *
     * @param x
     *            X coordinates of polyline.
     * @param y
     *            Y coordinates of polyline.
     * @param z
     *            Z coordinates of polyline. May be null if this is a 2D case.
     * @param xExtent
     *            Will upon return contain [xMin,xMax].
     * @param yExtent
     *            Will upon return contain [xMin,xMax].
     * @param zExtent
     *            Will upon return contain [xMin,xMax]. Unused (may be set to
     *            null) if z is null.
     */
    public static void findPolygonExtent(double[] x, double[] y, double[] z,
            double[] xExtent, double[] yExtent, double[] zExtent) {
        double xMin = +Double.MAX_VALUE;
        double xMax = -Double.MAX_VALUE;



        double yMin = +Double.MAX_VALUE;
        double yMax = -Double.MAX_VALUE;



        double zMin = +Double.MAX_VALUE;
        double zMax = -Double.MAX_VALUE;



        for (int i = 0; i < x.length; i++) {
            if (x[i] < xMin)
                xMin = x[i];
            if (x[i] > xMax)
                xMax = x[i];



            if (y[i] < yMin)
                yMin = y[i];
            if (y[i] > yMax)
                yMax = y[i];



            if (z != null) {
                if (z[i] < zMin)
                    zMin = z[i];
                if (z[i] > zMax)
                    zMax = z[i];
            }
        }



        xExtent[0] = xMin;
        xExtent[1] = xMax;



        yExtent[0] = yMin;
        yExtent[1] = yMax;



        if (z != null) {
            zExtent[0] = zMin;
            zExtent[1] = zMax;
        }
    }



    /**
     * Find the extent of a polygon.
     *
     * @param x
     *            X coordinates of polygon.
     * @param y
     *            Y coordinates of polygon.
     * @param xExtent
     *            Will upon return contain [xMin, xMax]
     * @param yExtent
     *            Will upon return contain [yMin, yMax]
     */
    public static void findPolygonExtent(int[] x, int[] y, int[] xExtent, // xMin,
                                                                            // xMax
            int[] yExtent) // yMin, yMax
    {
        int xMin = +Integer.MAX_VALUE;
        int xMax = -Integer.MAX_VALUE;



        int yMin = +Integer.MAX_VALUE;
        int yMax = -Integer.MAX_VALUE;



        for (int i = 0; i < x.length; i++) {
            if (x[i] < xMin)
                xMin = x[i];
            if (x[i] > xMax)
                xMax = x[i];



            if (y[i] < yMin)
                yMin = y[i];
            if (y[i] > yMax)
                yMax = y[i];
        }



        xExtent[0] = xMin;
        xExtent[1] = xMax;



        yExtent[0] = yMin;
        yExtent[1] = yMax;
    }



    /**
     * Compute the intersection between two line segments, or two lines of
     * infinite length.
     *
     * @param x0
     *            X coordinate first end point first line segment.
     * @param y0
     *            Y coordinate first end point first line segment.
     * @param x1
     *            X coordinate second end point first line segment.
     * @param y1
     *            Y coordinate second end point first line segment.
     * @param x2
     *            X coordinate first end point second line segment.
     * @param y2
     *            Y coordinate first end point second line segment.
     * @param x3
     *            X coordinate second end point second line segment.
     * @param y3
     *            Y coordinate second end point second line segment.
     * @param intersection
     *            [2] Preallocated by caller to double[2]
     * @return -1 if lines are parallel (x,y unset), -2 if lines are parallel
     *         and overlapping (x, y center) 0 if intesrection outside segments
     *         (x,y set) +1 if segments intersect (x,y set)
     */
    public static int findLineSegmentIntersection(double x0, double y0,
            double x1, double y1, double x2, double y2, double x3, double y3,
            double[] intersection) {
        // TODO: Make limit depend on input domain
        final double LIMIT = 1e-5;
        final double INFINITY = 1e10;



        double x, y;



        //
        // Convert the lines to the form y = ax + b
        //



        // Slope of the two lines
        double a0 = Geometry.equals(x0, x1, LIMIT) ? INFINITY : (y0 - y1)
                / (x0 - x1);
        double a1 = Geometry.equals(x2, x3, LIMIT) ? INFINITY : (y2 - y3)
                / (x2 - x3);



        double b0 = y0 - a0 * x0;
        double b1 = y2 - a1 * x2;



        // Check if lines are parallel
        if (Geometry.equals(a0, a1)) {
            if (!Geometry.equals(b0, b1))
                return -1; // Parallell non-overlapping



            else {
                if (Geometry.equals(x0, x1)) {
                    if (Math.min(y0, y1) < Math.max(y2, y3)
                            || Math.max(y0, y1) > Math.min(y2, y3)) {
                        double twoMiddle = y0 + y1 + y2 + y3
                                - Geometry.min(y0, y1, y2, y3)
                                - Geometry.max(y0, y1, y2, y3);
                        y = (twoMiddle) / 2.0;
                        x = (y - b0) / a0;
                    } else
                        return -1; // Parallell non-overlapping
                } else {
                    if (Math.min(x0, x1) < Math.max(x2, x3)
                            || Math.max(x0, x1) > Math.min(x2, x3)) {
                        double twoMiddle = x0 + x1 + x2 + x3
                                - Geometry.min(x0, x1, x2, x3)
                                - Geometry.max(x0, x1, x2, x3);
                        x = (twoMiddle) / 2.0;
                        y = a0 * x + b0;
                    } else
                        return -1;
                }



                intersection[0] = x;
                intersection[1] = y;
                return -2;
            }
        }



        // Find correct intersection point
        if (Geometry.equals(a0, INFINITY)) {
            x = x0;
            y = a1 * x + b1;
        } else if (Geometry.equals(a1, INFINITY)) {
            x = x2;
            y = a0 * x + b0;
        } else {
            x = -(b0 - b1) / (a0 - a1);
            y = a0 * x + b0;
        }



        intersection[0] = x;
        intersection[1] = y;



        // Then check if intersection is within line segments
        double distanceFrom1;
        if (Geometry.equals(x0, x1)) {
            if (y0 < y1)
                distanceFrom1 = y < y0 ? Geometry.length(x, y, x0, y0)
                        : y > y1 ? Geometry.length(x, y, x1, y1) : 0.0;
            else
                distanceFrom1 = y < y1 ? Geometry.length(x, y, x1, y1)
                        : y > y0 ? Geometry.length(x, y, x0, y0) : 0.0;
        } else {
            if (x0 < x1)
                distanceFrom1 = x < x0 ? Geometry.length(x, y, x0, y0)
                        : x > x1 ? Geometry.length(x, y, x1, y1) : 0.0;
            else
                distanceFrom1 = x < x1 ? Geometry.length(x, y, x1, y1)
                        : x > x0 ? Geometry.length(x, y, x0, y0) : 0.0;
        }



        double distanceFrom2;
        if (Geometry.equals(x2, x3)) {
            if (y2 < y3)
                distanceFrom2 = y < y2 ? Geometry.length(x, y, x2, y2)
                        : y > y3 ? Geometry.length(x, y, x3, y3) : 0.0;
            else
                distanceFrom2 = y < y3 ? Geometry.length(x, y, x3, y3)
                        : y > y2 ? Geometry.length(x, y, x2, y2) : 0.0;
        } else {
            if (x2 < x3)
                distanceFrom2 = x < x2 ? Geometry.length(x, y, x2, y2)
                        : x > x3 ? Geometry.length(x, y, x3, y3) : 0.0;
            else
                distanceFrom2 = x < x3 ? Geometry.length(x, y, x3, y3)
                        : x > x2 ? Geometry.length(x, y, x2, y2) : 0.0;
        }



        return Geometry.equals(distanceFrom1, 0.0)
                && Geometry.equals(distanceFrom2, 0.0) ? 1 : 0;
    }



    /**
     * Find the intersections between a polygon and a straight line.
     *
     * NOTE: This method is only guaranteed to work if the polygon is first
     * preprocessed so that "unneccesary" vertices are removed (i.e vertices on
     * the straight line between its neighbours).
     *
     * @param x
     *            X coordinates of polygon.
     * @param y
     *            Y coordinates of polygon.
     * @param x0
     *            X first end point of line.
     * @param x0
     *            Y first end point of line.
     * @param x0
     *            X second end point of line.
     * @param x0
     *            Y second end point of line.
     * @return Intersections [x,y,x,y...].
     */
    public static double[] findLinePolygonIntersections(double[] x, double[] y,
            double x0, double y0, double x1, double y1) {
        double x2, y2, x3, y3;
        double xi, yi;
        int nPoints = x.length;



        int nIntersections = 0;
        double[] intersections = new double[24]; // Result vector x,y,x,y,...
        double[] intersection = new double[2]; // Any given intersection x,y



        for (int i = 0; i < nPoints; i++) {
            int next = i == nPoints - 1 ? 0 : i + 1;



            // The line segment of the polyline to check
            x2 = x[i];
            y2 = y[i];
            x3 = x[next];
            y3 = y[next];



            boolean isIntersecting = false;



            // Ignore segments of zero length
            if (Geometry.equals(x2, x3) && Geometry.equals(y2, y3))
                continue;



            int type = Geometry.findLineSegmentIntersection(x0, y0, x1, y1, x2,
                    y2, x3, y3, intersection);



            if (type == -2) { // Overlapping
                int p1 = i == 0 ? nPoints - 1 : i - 1;
                int p2 = next == nPoints - 1 ? 0 : next + 1;



                int side = Geometry.sameSide(x0, y0, x1, y1, x[p1], y[p1],
                        x[p2], y[p2]);



                if (side < 0)
                    isIntersecting = true;
            } else if (type == 1)
                isIntersecting = true;



            // Add the intersection point
            if (isIntersecting) {



                // Reallocate if necessary
                if (nIntersections << 1 == intersections.length) {
                    double[] newArray = new double[nIntersections << 2];
                    System.arraycopy(intersections, 0, newArray, 0,
                            intersections.length);
                    intersections = newArray;
                }



                // Then add
                intersections[nIntersections << 1 + 0] = intersection[0];
                intersections[nIntersections << 1 + 1] = intersection[1];



                nIntersections++;
            }
        }



        if (nIntersections == 0)
            return null;



        // Reallocate result so array match number of intersections
        double[] finalArray = new double[nIntersections << 2];
        System.arraycopy(intersections, 0, finalArray, 0, finalArray.length);



        return finalArray;
    }



    /**
     * Return the geometry of an ellipse based on its four top points. Integer
     * domain. The method use the generic createEllipse() method for the main
     * task, and then transforms this according to any rotation or skew defined
     * by the given top points.
     *
     * @param x
     *            X array of four top points of ellipse.
     * @param y
     *            Y array of four top points of ellipse.
     * @return Geometry of ellipse [x,y,x,y...].
     */
    public static int[] createEllipse(int[] x, int[] y) {
        // Center of ellipse
        int x0 = (x[0] + x[2]) / 2;
        int y0 = (y[0] + y[2]) / 2;



        // Angle between axis define skew
        double[] p0 = { (double) x0, (double) y0, 0.0 };
        double[] p1 = { (double) x[0], (double) y[0], 0.0 };
        double[] p2 = { (double) x[1], (double) y[1], 0.0 };



        double axisAngle = Geometry.computeAngle(p0, p1, p2);



        // dx / dy
        double dx = Geometry.length(x0, y0, x[1], y[1]);
        double dy = Geometry.length(x0, y0, x[0], y[0]) * Math.sin(axisAngle);



        // Create geometry for unrotated / unsheared ellipse
        int[] ellipse = createEllipse(x0, y0, (int) Math.round(dx),
                (int) Math.round(dy));
        int nPoints = ellipse.length / 2;



        // Shear if neccessary. If angle is close to 90 there is no shear.
        // If angle is close to 0 or 180 shear is infinite, and we set
        // it to zero as well.
        if (!Geometry.equals(axisAngle, Math.PI / 2.0, 0.1)
                && !Geometry.equals(axisAngle, Math.PI, 0.1)
                && !Geometry.equals(axisAngle, 0.0, 0.1)) {
            double xShear = 1.0 / Math.tan(axisAngle);
            for (int i = 0; i < nPoints; i++)
                ellipse[i * 2 + 0] += Math.round((ellipse[i * 2 + 1] - y0)
                        * xShear);
        }



        // Rotate
        int ddx = x[1] - x0;
        int ddy = y0 - y[1];



        double angle;
        if (ddx == 0 && ddy == 0)
            angle = 0.0;
        else if (ddx == 0)
            angle = Math.PI / 2.0;
        else
            angle = Math.atan((double) ddy / (double) ddx);



        double cosAngle = Math.cos(angle);
        double sinAngle = Math.sin(angle);



        for (int i = 0; i < nPoints; i++) {
            int xr = (int) Math.round(x0 + (ellipse[i * 2 + 0] - x0) * cosAngle
                    - (ellipse[i * 2 + 1] - y0) * sinAngle);
            int yr = (int) Math.round(y0 - (ellipse[i * 2 + 1] - y0) * cosAngle
                    - (ellipse[i * 2 + 0] - x0) * sinAngle);



            ellipse[i * 2 + 0] = xr;
            ellipse[i * 2 + 1] = yr;
        }



        return ellipse;
    }



    /**
     * Create the geometry for an unrotated, unskewed ellipse. Integer domain.
     *
     * @param x0
     *            X center of ellipse.
     * @param y0
     *            Y center of ellipse.
     * @param dx
     *            X ellipse radius.
     * @param dy
     *            Y ellipse radius.
     * @return Ellipse geometry [x,y,x,y,...].
     */
    public static int[] createEllipse(int x0, int y0, int dx, int dy) {
        // Make sure deltas are positive
        dx = Math.abs(dx);
        dy = Math.abs(dy);



        // This is an approximate number of points we need to make a smooth
        // surface on a quater of the ellipse
        int nPoints = dx > dy ? dx : dy;
        nPoints /= 2;
        if (nPoints < 1)
            nPoints = 1;



        // Allocate arrays for holding the complete set of vertices around
        // the ellipse. Note that this is a complete ellipse: First and last
        // point coincide.
        int[] ellipse = new int[nPoints * 8 + 2];



        // Compute some intermediate results to save time in the inner loop
        int dxdy = dx * dy;
        int dx2 = dx * dx;
        int dy2 = dy * dy;



        // Handcode the entries in the four "corner" points of the ellipse,
        // i.e. at point 0, 90, 180, 270 and 360 degrees
        ellipse[nPoints * 0 + 0] = x0 + dx;
        ellipse[nPoints * 0 + 1] = y0;



        ellipse[nPoints * 8 + 0] = x0 + dx;
        ellipse[nPoints * 8 + 1] = y0;



        ellipse[nPoints * 2 + 0] = x0;
        ellipse[nPoints * 2 + 1] = y0 - dy;



        ellipse[nPoints * 4 + 0] = x0 - dx;
        ellipse[nPoints * 4 + 1] = y0;



        ellipse[nPoints * 6 + 0] = x0;
        ellipse[nPoints * 6 + 1] = y0 + dy;



        // Find the angle step
        double angleStep = nPoints > 0 ? Math.PI / 2.0 / nPoints : 0.0;



        // Loop over angles from 0 to 90. The rest of the ellipse can be
        // derrived
        // from this first quadrant. For each angle set the four corresponding
        // ellipse points.
        double a = 0.0;
        for (int i = 1; i < nPoints; i++) {
            a += angleStep;



            double t = Math.tan(a);



            double x = (double) dxdy / Math.sqrt(t * t * dx2 + dy2);
            double y = x * t;



            int xi = (int) (x + 0.5);
            int yi = (int) (y + 0.5);



            ellipse[(nPoints * 0 + i) * 2 + 0] = x0 + xi;
            ellipse[(nPoints * 2 - i) * 2 + 0] = x0 - xi;
            ellipse[(nPoints * 2 + i) * 2 + 0] = x0 - xi;
            ellipse[(nPoints * 4 - i) * 2 + 0] = x0 + xi;



            ellipse[(nPoints * 0 + i) * 2 + 1] = y0 - yi;
            ellipse[(nPoints * 2 - i) * 2 + 1] = y0 - yi;
            ellipse[(nPoints * 2 + i) * 2 + 1] = y0 + yi;
            ellipse[(nPoints * 4 - i) * 2 + 1] = y0 + yi;
        }



        return ellipse;
    }



    /**
     * Create the geometry for an unrotated, unskewed ellipse. Floating point
     * domain.
     *
     * @param x0
     *            X center of ellipse.
     * @param y0
     *            Y center of ellipse.
     * @param dx
     *            X ellipse radius.
     * @param dy
     *            Y ellipse radius.
     * @return Ellipse geometry [x,y,x,y,...].
     */
    public static double[] createEllipse(double x0, double y0, double dx,
            double dy) {
        // Make sure deltas are positive
        dx = Math.abs(dx);
        dy = Math.abs(dy);



        // As we don't know the resolution of the appliance of the ellipse
        // we create one vertex per 2nd degree. The nPoints variable holds
        // number of points in a quater of the ellipse.
        int nPoints = 45;



        // Allocate arrays for holding the complete set of vertices around
        // the ellipse. Note that this is a complete ellipse: First and last
        // point coincide.
        double[] ellipse = new double[nPoints * 8 + 2];



        // Compute some intermediate results to save time in the inner loop
        double dxdy = dx * dy;
        double dx2 = dx * dx;
        double dy2 = dy * dy;



        // Handcode the entries in the four "corner" points of the ellipse,
        // i.e. at point 0, 90, 180, 270 and 360 degrees
        ellipse[nPoints * 0 + 0] = x0 + dx;
        ellipse[nPoints * 0 + 1] = y0;



        ellipse[nPoints * 8 + 0] = x0 + dx;
        ellipse[nPoints * 8 + 1] = y0;



        ellipse[nPoints * 2 + 0] = x0;
        ellipse[nPoints * 2 + 1] = y0 - dy;



        ellipse[nPoints * 4 + 0] = x0 - dx;
        ellipse[nPoints * 4 + 1] = y0;



        ellipse[nPoints * 6 + 0] = x0;
        ellipse[nPoints * 6 + 1] = y0 + dy;



        // Find the angle step
        double angleStep = nPoints > 0 ? Math.PI / 2.0 / nPoints : 0.0;



        // Loop over angles from 0 to 90. The rest of the ellipse can be
        // derrived
        // from this first quadrant. For each angle set the four corresponding
        // ellipse points.
        double a = 0.0;
        for (int i = 1; i < nPoints; i++) {
            a += angleStep;



            double t = Math.tan(a);



            double x = (double) dxdy / Math.sqrt(t * t * dx2 + dy2);
            double y = x * t + 0.5;



            ellipse[(nPoints * 0 + i) * 2 + 0] = x0 + x;
            ellipse[(nPoints * 2 - i) * 2 + 0] = x0 - x;
            ellipse[(nPoints * 2 + i) * 2 + 0] = x0 - x;
            ellipse[(nPoints * 4 - i) * 2 + 0] = x0 + x;



            ellipse[(nPoints * 0 + i) * 2 + 1] = y0 - y;
            ellipse[(nPoints * 2 - i) * 2 + 1] = y0 - y;
            ellipse[(nPoints * 2 + i) * 2 + 1] = y0 + y;
            ellipse[(nPoints * 4 - i) * 2 + 1] = y0 + y;
        }



        return ellipse;
    }



    /**
     * Create geometry for a circle. Integer domain.
     *
     * @param x0
     *            X center of circle.
     * @param y0
     *            Y center of circle.
     * @param radius
     *            Radius of circle.
     * @return Geometry of circle [x,y,...]
     */
    public static int[] createCircle(int x0, int y0, int radius) {
        return createEllipse(x0, y0, radius, radius);
    }



    /**
     * Create geometry for a circle. Floating point domain.
     *
     * @param x0
     *            X center of circle.
     * @param y0
     *            Y center of circle.
     * @param radius
     *            Radius of circle.
     * @return Geometry of circle [x,y,...]
     */
    public static double[] createCircle(double x0, double y0, double radius) {
        return createEllipse(x0, y0, radius, radius);
    }



    /**
     * Create the geometry of a sector of an ellipse.
     *
     * @param x0
     *            X coordinate of center of ellipse.
     * @param y0
     *            Y coordinate of center of ellipse.
     * @param dx
     *            X radius of ellipse.
     * @param dy
     *            Y radius of ellipse.
     * @param angle0
     *            First angle of sector (in radians).
     * @param angle1
     *            Second angle of sector (in radians).
     * @return Geometry of secor [x,y,...]
     */
    public static int[] createSector(int x0, int y0, int dx, int dy,
            double angle0, double angle1) {
        // Determine a sensible number of points for arc
        double angleSpan = Math.abs(angle1 - angle0);
        double arcDistance = Math.max(dx, dy) * angleSpan;
        int nPoints = (int) Math.round(arcDistance / 15);
        double angleStep = angleSpan / (nPoints - 1);



        int[] xy = new int[nPoints * 2 + 4];



        int index = 0;
        for (int i = 0; i < nPoints; i++) {
            double angle = angle0 + angleStep * i;
            double x = dx * Math.cos(angle);
            double y = dy * Math.sin(angle);



            xy[index + 0] = x0 + (int) Math.round(x);
            xy[index + 1] = y0 - (int) Math.round(y);



            index += 2;
        }



        // Start and end geometry at center of ellipse to make it a closed
        // polygon
        xy[nPoints * 2 + 0] = x0;
        xy[nPoints * 2 + 1] = y0;
        xy[nPoints * 2 + 2] = xy[0];
        xy[nPoints * 2 + 3] = xy[1];



        return xy;
    }



    /**
     * Create the geometry of a sector of a circle.
     *
     * @param x0
     *            X coordinate of center of ellipse.
     * @param y0
     *            Y coordinate of center of ellipse.
     * @param dx
     *            X radius of ellipse.
     * @param dy
     *            Y radius of ellipse.
     * @param angle0
     *            First angle of sector (in radians).
     * @param angle1
     *            Second angle of sector (in radians).
     * @return Geometry of secor [x,y,...]
     */
    public static int[] createSector(int x0, int y0, int radius, double angle0,
            double angle1) {
        return createSector(x0, y0, radius, radius, angle0, angle1);
    }



    /**
     * Create the geometry of an arrow. The arrow is positioned at the end (last
     * point) of the specified polyline, as follows:
     *
     * 0,4--, \ --, \ --, \ --, \ --, -------------------------3-----------1 /
     * --' / --' / --' / --' 2--'
     *
     * @param x
     *            X coordinates of polyline of where arrow is positioned in the
     *            end. Must contain at least two points.
     * @param y
     *            Y coordinates of polyline of where arrow is positioned in the
     *            end.
     * @param length
     *            Length along the main axis from point 1 to the projection of
     *            point 0.
     * @param angle
     *            Angle between the main axis and the line 1,0 (and 1,2) in
     *            radians.
     * @param inset
     *            Specification of point 3 [0.0-1.0], 1.0 will put point 3 at
     *            distance length from 1, 0.0 will put it at point 1.
     * @return Array of the five coordinates [x,y,...].
     */
    public static int[] createArrow(int[] x, int[] y, double length,
            double angle, double inset) {
        int[] arrow = new int[10];



        int x0 = x[x.length - 1];
        int y0 = y[y.length - 1];



        arrow[2] = x0;
        arrow[3] = y0;



        // Find position of interior of the arrow along the polyline
        int[] pos1 = new int[2];
        Geometry.findPolygonPosition(x, y, length, pos1);



        // Angles
        double dx = x0 - pos1[0];
        double dy = y0 - pos1[1];



        // Polyline angle
        double v = dx == 0.0 ? Math.PI / 2.0 : Math.atan(Math.abs(dy / dx));



        v = dx > 0.0 && dy <= 0.0 ? Math.PI + v
                : dx > 0.0 && dy >= 0.0 ? Math.PI - v
                        : dx <= 0.0 && dy < 0.0 ? -v
                                : dx <= 0.0 && dy > 0.0 ? +v : 0.0;



        double v0 = v + angle;
        double v1 = v - angle;



        double edgeLength = length / Math.cos(angle);



        arrow[0] = x0 + (int) Math.round(edgeLength * Math.cos(v0));
        arrow[1] = y0 - (int) Math.round(edgeLength * Math.sin(v0));



        arrow[4] = x0 + (int) Math.round(edgeLength * Math.cos(v1));
        arrow[5] = y0 - (int) Math.round(edgeLength * Math.sin(v1));



        double c1 = inset * length;



        arrow[6] = x0 + (int) Math.round(c1 * Math.cos(v));
        arrow[7] = y0 - (int) Math.round(c1 * Math.sin(v));



        // Close polygon
        arrow[8] = arrow[0];
        arrow[9] = arrow[1];



        return arrow;
    }



    /**
     * Create geometry for an arrow along the specified line and with tip at
     * x1,y1. See general method above.
     *
     * @param x0
     *            X first end point of line.
     * @param y0
     *            Y first end point of line.
     * @param x1
     *            X second end point of line.
     * @param y1
     *            Y second end point of line.
     * @param length
     *            Length along the main axis from point 1 to the projection of
     *            point 0.
     * @param angle
     *            Angle between the main axis and the line 1,0 (and 1.2)
     * @param inset
     *            Specification of point 3 [0.0-1.0], 1.0 will put point 3 at
     *            distance length from 1, 0.0 will put it at point 1.
     * @return Array of the four coordinates [x,y,...].
     */
    public static int[] createArrow(int x0, int y0, int x1, int y1,
            double length, double angle, double inset) {
        int[] x = { x0, x1 };
        int[] y = { y0, y1 };



        return createArrow(x, y, length, angle, inset);
    }



    /**
     * Create geometry for a rectangle. Returns a closed polygon; first and last
     * points matches. Integer domain.
     *
     * @param x0
     *            X corner of rectangle.
     * @param y0
     *            Y corner of rectangle.
     * @param width
     *            Width (may be negative to indicate leftwards direction)
     * @param height
     *            Height (may be negative to indicaten upwards direction)
     */
    public static int[] createRectangle(int x0, int y0, int width, int height) {
        return new int[] { x0, y0, x0 + (width - 1), y0, x0 + (width - 1),
                y0 + (height - 1), x0, y0 + (height - 1), x0, y0 };
    }



    /**
     * Create geometry for a rectangle. Returns a closed polygon; first and last
     * points matches. Floating point domain.
     *
     * @param x0
     *            X corner of rectangle.
     * @param y0
     *            Y corner of rectangle.
     * @param width
     *            Width (may be negative to indicate leftwards direction)
     * @param height
     *            Height (may be negative to indicaten upwards direction)
     */
    public static double[] createRectangle(double x0, double y0, double width,
            double height) {
        return new double[] { x0, y0, x0 + width, y0, x0 + width, y0 + height,
                x0, y0 + height, x0, y0 };
    }



    /**
     * Create geometry of a star. Integer domain.
     *
     * @param x0
     *            X center of star.
     * @param y0
     *            Y center of star.
     * @param innerRadius
     *            Inner radis of arms.
     * @param outerRadius
     *            Outer radius of arms.
     * @param nArms
     *            Number of arms.
     * @return Geometry of star [x,y,x,y,...].
     */
    public static int[] createStar(int x0, int y0, int innerRadius,
            int outerRadius, int nArms) {
        int nPoints = nArms * 2 + 1;



        int[] xy = new int[nPoints * 2];



        double angleStep = 2.0 * Math.PI / nArms / 2.0;



        for (int i = 0; i < nArms * 2; i++) {
            double angle = i * angleStep;
            double radius = (i % 2) == 0 ? innerRadius : outerRadius;



            double x = x0 + radius * Math.cos(angle);
            double y = y0 + radius * Math.sin(angle);



            xy[i * 2 + 0] = (int) Math.round(x);
            xy[i * 2 + 1] = (int) Math.round(y);
        }



        // Close polygon
        xy[nPoints * 2 - 2] = xy[0];
        xy[nPoints * 2 - 1] = xy[1];



        return xy;
    }



    /**
     * Create geometry of a star. Floating point domain.
     *
     * @param x0
     *            X center of star.
     * @param y0
     *            Y center of star.
     * @param innerRadius
     *            Inner radis of arms.
     * @param outerRadius
     *            Outer radius of arms.
     * @param nArms
     *            Number of arms.
     * @return Geometry of star [x,y,x,y,...].
     */
    public static double[] createStar(double x0, double y0, double innerRadius,
            double outerRadius, int nArms) {
        int nPoints = nArms * 2 + 1;



        double[] xy = new double[nPoints * 2];



        double angleStep = 2.0 * Math.PI / nArms / 2.0;



        for (int i = 0; i < nArms * 2; i++) {
            double angle = i * angleStep;
            double radius = (i % 2) == 0 ? innerRadius : outerRadius;



            xy[i * 2 + 0] = x0 + radius * Math.cos(angle);
            xy[i * 2 + 1] = y0 + radius * Math.sin(angle);
        }



        // Close polygon
        xy[nPoints * 2 - 2] = xy[0];
        xy[nPoints * 2 - 1] = xy[1];



        return xy;
    }



    /**
     * Return the x,y position at distance "length" into the given polyline.
     *
     * @param x
     *            X coordinates of polyline
     * @param y
     *            Y coordinates of polyline
     * @param length
     *            Requested position
     * @param position
     *            Preallocated to int[2]
     * @return True if point is within polyline, false otherwise
     */
    public static boolean findPolygonPosition(int[] x, int[] y, double length,
            int[] position) {
        if (length < 0)
            return false;



        double accumulatedLength = 0.0;
        for (int i = 1; i < x.length; i++) {
            double legLength = Geometry.length(x[i - 1], y[i - 1], x[i], y[i]);
            if (legLength + accumulatedLength >= length) {
                double part = length - accumulatedLength;
                double fraction = part / legLength;
                position[0] = (int) Math.round(x[i - 1] + fraction
                        * (x[i] - x[i - 1]));
                position[1] = (int) Math.round(y[i - 1] + fraction
                        * (y[i] - y[i - 1]));
                return true;
            }



            accumulatedLength += legLength;
        }



        // Length is longer than polyline
        return false;
    }
}
And finally have look on last package
IconContextMenu.java
package com.dilip.Imagegallary;



import java.util.ArrayList;



import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.TextView;



/**
 * @author dilip
 *
 */
public class IconContextMenu implements DialogInterface.OnCancelListener,
        DialogInterface.OnDismissListener {



    private static final int LIST_PREFERED_HEIGHT = 65;



    private IconMenuAdaptepackage com.nexbits.Imagegallary;



import java.util.ArrayList;



/**
 * @author dilip
 *
 */
public class IconContextMenu implements DialogInterface.OnCancelListener,
        DialogInterface.OnDismissListener {



    private static final int LIST_PREFERED_HEIGHT = 65;



    private IconMenuAdapter menuAdapter = null;
    private Activity parentActivity = null;
    private int dialogId = 0;



    private IconContextMenuOnClickListener clickHandler = null;



    /**
     * constructor
     *
     * @param parent
     * @param id
     */
    public IconContextMenu(Activity parent, int id) {
        this.parentActivity = parent;
        this.dialogId = id;



        menuAdapter = new IconMenuAdapter(parentActivity);
    }



    /**
     * Add menu item
     *
     * @param menuItem
     */
    public void addItem(Resources res, CharSequence title, int imageResourceId,
            int actionTag) {
        menuAdapter.addItem(new IconContextMenuItem(res, title,
                imageResourceId, actionTag));
    }



    public void addItem(Resources res, int textResourceId, int imageResourceId,
            int actionTag) {
        menuAdapter.addItem(new IconContextMenuItem(res, textResourceId,
                imageResourceId, actionTag));
    }



    /**
     * Set menu onclick listener
     *
     * @param listener
     */
    public void setOnClickListener(IconContextMenuOnClickListener listener) {
        clickHandler = listener;
    }



    /**
     * Create menu
     *
     * @return
     */
    public Dialog createMenu(String menuItitle) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(
                parentActivity);
        builder.setTitle(menuItitle);
        builder.setAdapter(menuAdapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialoginterface, int i) {
                IconContextMenuItem item = (IconContextMenuItem) menuAdapter
                        .getItem(i);



                if (clickHandler != null) {
                    clickHandler.onClick(item.actionTag);
                }
            }
        });



        builder.setInverseBackgroundForced(true);



        AlertDialog dialog = builder.create();
        dialog.setOnCancelListener(this);
        dialog.setOnDismissListener(this);
        return dialog;
    }



    public void onCancel(DialogInterface dialog) {
        cleanup();
    }



    public void onDismiss(DialogInterface dialog) {
    }



    private void cleanup() {
        parentActivity.dismissDialog(dialogId);
    }



    /**
     * IconContextMenu On Click Listener interface
     */
    public interface IconContextMenuOnClickListener {
        public abstract void onClick(int menuId);
    }



    /**
     * Menu-like list adapter with icon
     */
    protected class IconMenuAdapter extends BaseAdapter {
        private Context context = null;



        private ArrayList<IconContextMenuItem> mItems = new ArrayList<IconContextMenuItem>();



        public IconMenuAdapter(Context context) {
            this.context = context;
        }



        /**
         * add item to adapter
         *
         * @param menuItem
         */
        public void addItem(IconContextMenuItem menuItem) {
            mItems.add(menuItem);
        }



        public int getCount() {
            return mItems.size();
        }



        public Object getItem(int position) {
            return mItems.get(position);
        }



        public long getItemId(int position) {
            IconContextMenuItem item = (IconContextMenuItem) getItem(position);
            return item.actionTag;
        }



        public View getView(int position, View convertView, ViewGroup parent) {
            IconContextMenuItem item = (IconContextMenuItem) getItem(position);



            Resources res = parentActivity.getResources();



            if (convertView == null) {
                TextView temp = new TextView(context);
                AbsListView.LayoutParams param = new AbsListView.LayoutParams(
                        AbsListView.LayoutParams.FILL_PARENT,
                        AbsListView.LayoutParams.WRAP_CONTENT);
                temp.setLayoutParams(param);
                temp.setPadding((int) toPixel(res, 15), 0,
                        (int) toPixel(res, 15), 0);
                temp.setGravity(android.view.Gravity.CENTER_VERTICAL);



                Theme th = context.getTheme();
                TypedValue tv = new TypedValue();



                if (th.resolveAttribute(
                        android.R.attr.textAppearanceLargeInverse, tv, true)) {
                    temp.setTextAppearance(context, tv.resourceId);
                }



                temp.setMinHeight(LIST_PREFERED_HEIGHT);
                temp.setCompoundDrawablePadding((int) toPixel(res, 14));
                convertView = temp;
            }



            TextView textView = (TextView) convertView;
            textView.setTag(item);
            textView.setText(item.text);
            textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null,
                    null, null);



            return textView;
        }



        private float toPixel(Resources res, int dip) {
            float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dip, res.getDisplayMetrics());
            return px;
        }
    }



    /**
     * menu-like list item with icon
     */
    protected class IconContextMenuItem {
        public final CharSequence text;
        public final Drawable image;
        public final int actionTag;



        /**
         * public constructor
         *
         * @param res
         *            resource handler
         * @param textResourceId
         *            id of title in resource
         * @param imageResourceId
         *            id of icon in resource
         * @param actionTag
         *            indicate action of menu item
         */
        public IconContextMenuItem(Resources res, int textResourceId,
                int imageResourceId, int actionTag) {
            text = res.getString(textResourceId);
            if (imageResourceId != -1) {
                image = res.getDrawable(imageResourceId);
            } else {
                image = null;
            }
            this.actionTag = actionTag;
        }



        /**
         * public constructor
         *
         * @param res
         *            resource handler
         * @param title
         *            menu item title
         * @param imageResourceId
         *            id of icon in resource
         * @param actionTag
         *            indicate action of menu item
         */
        public IconContextMenuItem(Resources res, CharSequence title,
                int imageResourceId, int actionTag) {
            text = title;
            if (imageResourceId != -1) {
                image = res.getDrawable(imageResourceId);
            } else {
                image = null;
            }
            this.actionTag = actionTag;
        }
    }
}
r menuAdapter = null;
    private Activity parentActivity = null;
    private int dialogId = 0;



    private IconContextMenuOnClickListener clickHandler = null;



    /**
     * constructor
     *
     * @param parent
     * @param id
     */
    public IconContextMenu(Activity parent, int id) {
        this.parentActivity = parent;
        this.dialogId = id;



        menuAdapter = new IconMenuAdapter(parentActivity);
    }



    /**
     * Add menu item
     *
     * @param menuItem
     */
    public void addItem(Resources res, CharSequence title, int imageResourceId,
            int actionTag) {
        menuAdapter.addItem(new IconContextMenuItem(res, title,
                imageResourceId, actionTag));
    }



    public void addItem(Resources res, int textResourceId, int imageResourceId,
            int actionTag) {
        menuAdapter.addItem(new IconContextMenuItem(res, textResourceId,
                imageResourceId, actionTag));
    }



    /**
     * Set menu onclick listener
     *
     * @param listener
     */
    public void setOnClickListener(IconContextMenuOnClickListener listener) {
        clickHandler = listener;
    }



    /**
     * Create menu
     *
     * @return
     */
    public Dialog createMenu(String menuItitle) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(
                parentActivity);
        builder.setTitle(menuItitle);
        builder.setAdapter(menuAdapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialoginterface, int i) {
                IconContextMenuItem item = (IconContextMenuItem) menuAdapter
                        .getItem(i);



                if (clickHandler != null) {
                    clickHandler.onClick(item.actionTag);
                }
            }
        });



        builder.setInverseBackgroundForced(true);



        AlertDialog dialog = builder.create();
        dialog.setOnCancelListener(this);
        dialog.setOnDismissListener(this);
        return dialog;
    }



    public void onCancel(DialogInterface dialog) {
        cleanup();
    }



    public void onDismiss(DialogInterface dialog) {
    }



    private void cleanup() {
        parentActivity.dismissDialog(dialogId);
    }



    /**
     * IconContextMenu On Click Listener interface
     */
    public interface IconContextMenuOnClickListener {
        public abstract void onClick(int menuId);
    }



    /**
     * Menu-like list adapter with icon
     */
    protected class IconMenuAdapter extends BaseAdapter {
        private Context context = null;



        private ArrayList<IconContextMenuItem> mItems = new ArrayList<IconContextMenuItem>();



        public IconMenuAdapter(Context context) {
            this.context = context;
        }



        /**
         * add item to adapter
         *
         * @param menuItem
         */
        public void addItem(IconContextMenuItem menuItem) {
            mItems.add(menuItem);
        }



        public int getCount() {
            return mItems.size();
        }



        public Object getItem(int position) {
            return mItems.get(position);
        }



        public long getItemId(int position) {
            IconContextMenuItem item = (IconContextMenuItem) getItem(position);
            return item.actionTag;
        }



        public View getView(int position, View convertView, ViewGroup parent) {
            IconContextMenuItem item = (IconContextMenuItem) getItem(position);



            Resources res = parentActivity.getResources();



            if (convertView == null) {
                TextView temp = new TextView(context);
                AbsListView.LayoutParams param = new AbsListView.LayoutParams(
                        AbsListView.LayoutParams.FILL_PARENT,
                        AbsListView.LayoutParams.WRAP_CONTENT);
                temp.setLayoutParams(param);
                temp.setPadding((int) toPixel(res, 15), 0,
                        (int) toPixel(res, 15), 0);
                temp.setGravity(android.view.Gravity.CENTER_VERTICAL);



                Theme th = context.getTheme();
                TypedValue tv = new TypedValue();



                if (th.resolveAttribute(
                        android.R.attr.textAppearanceLargeInverse, tv, true)) {
                    temp.setTextAppearance(context, tv.resourceId);
                }



                temp.setMinHeight(LIST_PREFERED_HEIGHT);
                temp.setCompoundDrawablePadding((int) toPixel(res, 14));
                convertView = temp;
            }



            TextView textView = (TextView) convertView;
            textView.setTag(item);
            textView.setText(item.text);
            textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null,
                    null, null);



            return textView;
        }



        private float toPixel(Resources res, int dip) {
            float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dip, res.getDisplayMetrics());
            return px;
        }
    }



    /**
     * menu-like list item with icon
     */
    protected class IconContextMenuItem {
        public final CharSequence text;
        public final Drawable image;
        public final int actionTag;



        /**
         * public constructor
         *
         * @param res
         *            resource handler
         * @param textResourceId
         *            id of title in resource
         * @param imageResourceId
         *            id of icon in resource
         * @param actionTag
         *            indicate action of menu item
         */
        public IconContextMenuItem(Resources res, int textResourceId,
                int imageResourceId, int actionTag) {
            text = res.getString(textResourceId);
            if (imageResourceId != -1) {
                image = res.getDrawable(imageResourceId);
            } else {
                image = null;
            }
            this.actionTag = actionTag;
        }



        /**
         * public constructor
         *
         * @param res
         *            resource handler
         * @param title
         *            menu item title
         * @param imageResourceId
         *            id of icon in resource
         * @param actionTag
         *            indicate action of menu item
         */
        public IconContextMenuItem(Resources res, CharSequence title,
                int imageResourceId, int actionTag) {
            text = title;
            if (imageResourceId != -1) {
                image = res.getDrawable(imageResourceId);
            } else {
                image = null;
            }
            this.actionTag = actionTag;
        }
    }
}
ImageGallary.java
package com.dilip.Imagegallary;



import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;



import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;



import com.nexbits.digitechi.HeaderAndButtonActivity;
import com.nexbits.digitechi.R;



public class ImageGallary extends HeaderAndButtonActivity {



    private static final String MEDIA_PATH = new String("/data/dilipimages");



    String[] fileList = null;
    String[] file = null;
    GridView gridView;
    String FILE_PATH = "/data/dilipimages/";
    private final int CONTEXT_MENU_ID = 1;
    private IconContextMenu iconContextMenu = null;
    String imageFilePath;
    private final int SHARE = 1;
    private final int DELETE = 2;



    @Override
    public void onCreate(Bundle savedInstanceState) {



        super.onCreate(savedInstanceState);
        setContentView(R.layout.igmain);
        updateSongList();
        Resources res = getResources();
        iconContextMenu = new IconContextMenu(this, CONTEXT_MENU_ID);
        iconContextMenu.addItem(res, "Share", R.drawable.share, SHARE);
        iconContextMenu.addItem(res, "Delete", R.drawable.delete1, DELETE);
        gridView = (GridView) findViewById(R.id.gridView1);
        if (fileList != null) {
            gridView.setAdapter(new ImageAdapter(this, fileList));
        }
        gridView.setOnItemLongClickListener(new OnItemLongClickListener() {



            public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                showDialog(CONTEXT_MENU_ID);
                imageFilePath = FILE_PATH + fileList[position];
                System.out
                        .println("******************************Value of imageFilePath*********************"
                                + imageFilePath);
                // TODO Auto-generated method stub
                return false;
            }
        });
        gridView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                    int position, long id) {
                SharedPreferences indexPrefs = getSharedPreferences(
                        "currentIndex", MODE_PRIVATE);



                SharedPreferences.Editor indexEditor = indexPrefs.edit();
                indexEditor.putInt("currentIndex", position);
                indexEditor.commit();
                final Intent intent = new Intent(ImageGallary.this,
                        ImageViewFlipper.class);
                startActivity(intent);



            }
        });
        iconContextMenu
                .setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
                    public void onClick(int menuId) {
                        switch (menuId) {
                        case SHARE:
                            Intent share = new Intent(Intent.ACTION_SEND);
                            System.out.println("***********************value of");
                            share.setType("image/jpeg");
                            // share.setType("video/3gpp");
                            share.putExtra(Intent.EXTRA_STREAM,
                                    Uri.parse("file://" + imageFilePath));
                            startActivity(Intent.createChooser(share,
                                    "Share Image"));
                            break;
                        case DELETE:



                            File file = new File(imageFilePath);
                            if (file.exists()) {
                                boolean deleted = file.delete();
                                sendBroadcast(new Intent(
                                        Intent.ACTION_MEDIA_MOUNTED,
                                        Uri.parse(imageFilePath
                                                + Environment
                                                        .getExternalStorageDirectory())));
                                if (deleted) {



                                    System.out
                                            .println("***********************>>>>>>>>>>>>>>>>>>>>>>>>>> DELETED ********");
                                    Toast.makeText(ImageGallary.this,
                                            "Deleted", 200).show();
                                    sendBroadcast(new Intent(
                                            Intent.ACTION_MEDIA_MOUNTED,
                                            Uri.parse("file://"
                                                    + imageFilePath
                                                    + Environment
                                                            .getExternalStorageDirectory())));



                                } else {
                                    System.out
                                            .println("***********************>>>>>>>>>>>>>>>>>>>>>>>>>>>NOT DELETED ********");
                                }



                            } else {
                                System.out
                                        .println("***********************>>>>>>>>>>>>>>>>>>>>>>>>>>>FILE DOESN'T EXIT ********");



                            }



                            break;



                        }
                    }
                });
    }



    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        overridePendingTransition(R.anim.right_slide_in, R.anim.right_slide_out);



    }



    @Override
    protected Dialog onCreateDialog(int id) {
        if (id == CONTEXT_MENU_ID) {
            return iconContextMenu.createMenu("Options");
        }
        return super.onCreateDialog(id);
    }



    public void updateSongList() {



        File videoFiles = new File(MEDIA_PATH);



        Log.d("*********Value of videoFiles******", videoFiles.toString());



        if (videoFiles.isDirectory()) {
            fileList = videoFiles.list();
        }
        if (fileList == null) {
            System.out.println("File doesnot exit");
            Toast.makeText(this, "There is no file", Toast.LENGTH_SHORT).show();
        } else {
            for (String f : fileList) {
                if (f.endsWith(".jpg")) {
                    file = fileList;
                }
            }
            System.out.println("fileList****************" + fileList);
            for (int i = 0; i < fileList.length; i++) {



                Log.e("Video:" + i + " File name", fileList[i]);
                Log.e("********Value of image:" + i + " File name", file[i]);



            }
        }



    }



    public class ImageAdapter extends BaseAdapter {
        private Context context;



        private final String[] VideoValues;



        public ImageAdapter(Context context, String[] VideoValues) {
            this.context = context;
            this.VideoValues = VideoValues;
        }



        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("***********IngetView************");
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);



            View gridView;



            if (convertView == null) {



                gridView = new View(context);



                // get layout from gridlayout.xml
                gridView = inflater.inflate(R.layout.gridlayout, null);



                // set value into textview
                TextView textView = (TextView) gridView
                        .findViewById(R.id.grid_item_label);
                textView.setText(fileList[position]);
                System.out.println("value of fileList[position]" + fileList[0]);
                // set image
                ImageView imageThumbnail = (ImageView) gridView
                        .findViewById(R.id.grid_item_image);



                byte[] imageData = null;
                try {



                    final int THUMBNAIL_SIZE = 64;
                    // InputStream
                    // is=getAssets().open("apple-android-battle.jpg");
                    FileInputStream fis = new FileInputStream(FILE_PATH
                            + fileList[position]);
                    Bitmap imageBitmap = BitmapFactory.decodeStream(fis);



                    Float width = new Float(imageBitmap.getWidth());
                    Float height = new Float(imageBitmap.getHeight());
                    Float ratio = width / height;
                    imageBitmap = Bitmap.createScaledBitmap(imageBitmap,
                            (int) (THUMBNAIL_SIZE * ratio), THUMBNAIL_SIZE,
                            false);



                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                    imageData = baos.toByteArray();
                    imageThumbnail.setImageBitmap(imageBitmap);
                } catch (Exception ex) {



                }



            } else {
                gridView = (View) convertView;
            }



            return gridView;
        }



        public int getCount() {
            // return 0;
            return VideoValues.length;
        }



        public Object getItem(int position) {
            return null;
        }



        public long getItemId(int position) {
            return 0;
        }



    }
}
ImageViewFlipper.java
package com.dilip.Imagegallary;



import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;



import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ViewFlipper;



import com.nexbits.android.ui.touch.TouchActivity;
import com.nexbits.android.util.FileUtils;
import com.nexbits.digitechi.R;



public class ImageViewFlipper extends TouchActivity {



    private static final int EXIT = 0;
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private static final String DIRECTORY = "/data/dilipimages";
    private static final String DATA_DIRECTORY = "/data/dilipimages.ImageGallary/";
    private static final String DATA_FILE = "/data/dilipimages.ImageGallary/imagelist.dat";
    private GestureDetector gestureDetector;
    View.OnTouchListener gestureListener;
    private Animation slideLeftIn;
    private Animation slideLeftOut;
    private Animation slideRightIn;
    private Animation slideRightOut;
    private ViewFlipper viewFlipper;
    private int currentView = 0;
    List<String> ImageList;
    private int currentIndex = 0;
    private int maxIndex = 0;
    private float mMinZoomScale = 1;



    FileOutputStream output = null;
    OutputStreamWriter writer = null;



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



        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);



        setContentView(R.layout.imagemain);
        ImageView iv = (ImageView) findViewById(R.id.zero);
        /*
         * iv.setOnTouchListener(this);
         * findViewById(R.id.one).setOnTouchListener(this);
         * findViewById(R.id.two).setOnTouchListener(this);
         */



        File data_directory = new File(DATA_DIRECTORY);
        if (!data_directory.exists()) {
            if (data_directory.mkdir()) {
                FileUtils savedata = new FileUtils();
                Toast toast = Toast
                        .makeText(
                                ImageViewFlipper.this,
                                "Please wait while we search your SD Card for images...",
                                Toast.LENGTH_SHORT);
                toast.show();
                SystemClock.sleep(100);
                ImageList = FindFiles();
                savedata.saveArray(DATA_FILE, ImageList);



            } else {
                ImageList = FindFiles();
            }



        } else {
            File data_file = new File(DATA_FILE);
            if (!data_file.exists()) {
                FileUtils savedata = new FileUtils();
                Toast toast = Toast
                        .makeText(
                                ImageViewFlipper.this,
                                "Please wait while we search your SD Card for images...",
                                Toast.LENGTH_SHORT);
                toast.show();
                SystemClock.sleep(100);
                ImageList = FindFiles();
                savedata.saveArray(DATA_FILE, ImageList);
            } else {
                FileUtils readdata = new FileUtils();
                ImageList = readdata.loadArray(DATA_FILE);
            }
        }



        if (ImageList == null) {
            quit();
        }



        SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
                MODE_PRIVATE);
        if (indexPrefs.contains("currentIndex")) {
            currentIndex = indexPrefs.getInt("currentIndex", 0);
        }



        maxIndex = ImageList.size() - 1;



        Log.v("currentIndex", "Index: " + currentIndex);



        viewFlipper = (ViewFlipper) findViewById(R.id.flipper);



        slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
        slideLeftOut = AnimationUtils
                .loadAnimation(this, R.anim.slide_left_out);
        slideRightIn = AnimationUtils
                .loadAnimation(this, R.anim.slide_right_in);
        slideRightOut = AnimationUtils.loadAnimation(this,
                R.anim.slide_right_out);



        viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
                android.R.anim.fade_in));
        viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
                android.R.anim.fade_out));
        Drawable d = Drawable.createFromPath(ImageList.get(currentIndex));
        iv.setImageDrawable(d);
        resetImage(iv, d);
        System.gc();



        gestureDetector = new GestureDetector(new MyGestureDetector());
        gestureListener = new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        };
    }



    public void shareimage(View v) {



        /*
         * Intent share = new Intent(Intent.ACTION_SEND);
         * share.setType("image/jpeg");
         *
         * share.putExtra(Intent.EXTRA_STREAM,Uri.parse(
         * "file:///mnt/sdcard/FreedomMic/test/v1327056571768.3gpp"));
         *
         * startActivity(Intent.createChooser(share, "Share Image"));
         */



    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        int NONE = Menu.NONE;
        menu.add(NONE, EXIT, NONE, "Exit");
        return true;
    }



    protected void onPause() {
        super.onPause();



        SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
                MODE_PRIVATE);



        SharedPreferences.Editor indexEditor = indexPrefs.edit();
        indexEditor.putInt("currentIndex", currentIndex);
        indexEditor.commit();
    }



    protected void onResume() {
        super.onResume();
        SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
                MODE_PRIVATE);
        if (indexPrefs.contains("currentIndex")) {
            currentIndex = indexPrefs.getInt("currentIndex", 0);
        }
    }



    private List<String> FindFiles() {
        final List<String> tFileList = new ArrayList<String>();
        Resources resources = getResources();
        // array of valid image file extensions
        String[] imageTypes = resources.getStringArray(R.array.image);
        FilenameFilter[] filter = new FilenameFilter[imageTypes.length];



        int i = 0;
        for (final String type : imageTypes) {
            filter[i] = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith("." + type);
                }
            };
            i++;
        }



        FileUtils fileUtils = new FileUtils();
        File[] allMatchingFiles = fileUtils.listFilesAsArray(
                new File(DIRECTORY), filter, -1);
        for (File f : allMatchingFiles) {
            tFileList.add(f.getAbsolutePath());
        }
        return tFileList;
    }



    class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onDoubleTap(final MotionEvent e) {



            ImageView view = (ImageView) findViewById(R.id.zero);
            switch (currentView) {
            case 0:
                view = (ImageView) findViewById(R.id.zero);
                break;
            case 1:
                view = (ImageView) findViewById(R.id.one);
                break;
            case 2:
                view = (ImageView) findViewById(R.id.two);
                break;
            }



            resetImage(view, view.getDrawable());
            return true;
        }



        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;
                // right to left swipe
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                        && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    viewFlipper.setInAnimation(slideLeftIn);
                    viewFlipper.setOutAnimation(slideLeftOut);



                    if (currentIndex == maxIndex) {
                        currentIndex = 0;
                    } else {
                        currentIndex = currentIndex + 1;
                    }
                    ImageView iv;
                    Drawable d = Drawable.createFromPath(ImageList
                            .get(currentIndex));



                    if (currentView == 0) {
                        currentView = 1;
                        iv = (ImageView) findViewById(R.id.one);



                        iv.setImageDrawable(d);



                        System.gc();
                    } else if (currentView == 1) {
                        currentView = 2;
                        iv = (ImageView) findViewById(R.id.two);



                        iv.setImageDrawable(d);
                        System.gc();
                    } else {
                        currentView = 0;
                        iv = (ImageView) findViewById(R.id.zero);



                        iv.setImageDrawable(d);
                        System.gc();
                    }
                    resetImage(iv, d);
                    Log.v("ImageViewFlipper", "Current View: " + currentView);
                    viewFlipper.showNext();



                    return true;
                } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                        && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    viewFlipper.setInAnimation(slideRightIn);
                    viewFlipper.setOutAnimation(slideRightOut);



                    if (currentIndex == 0) {
                        currentIndex = maxIndex;
                    } else {
                        currentIndex = currentIndex - 1;
                    }
                    ImageView iv;
                    Drawable d = Drawable.createFromPath(ImageList
                            .get(currentIndex));
                    if (currentView == 0) {
                        currentView = 2;
                        iv = (ImageView) findViewById(R.id.two);
                        iv.setImageDrawable(d);
                        System.gc();
                    } else if (currentView == 2) {
                        currentView = 1;
                        iv = (ImageView) findViewById(R.id.one);
                        iv.setImageDrawable(d);
                        System.gc();
                    } else {
                        currentView = 0;
                        iv = (ImageView) findViewById(R.id.zero);
                        iv.setImageDrawable(d);
                        System.gc();
                    }
                    resetImage(iv, d);
                    Log.v("ImageViewFlipper", "Current View: " + currentView);
                    viewFlipper.showPrevious();
                    return true;
                }
            } catch (Exception e) {
                // nothing
            }
            return false;
        }



    }



    @Override
    public void resetImage(ImageView iv, Drawable draw) {
        Display display = ((WindowManager) getSystemService(WINDOW_SERVICE))
                .getDefaultDisplay();
        int rotation = display.getRotation();



        int orientation = 0;
        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180)
            orientation = 0;
        else
            orientation = 1;



        matrix = new Matrix();
        matrix.setTranslate(1f, 1f);
        float scale = 1;



        mMinZoomScale = 1;
        if (orientation == 0
        // && (float)draw.getIntrinsicWidth() >
        // (float)getWindowManager().getDefaultDisplay().getWidth()
        ) {



            scale = (float) getWindowManager().getDefaultDisplay().getWidth()
                    / (float) draw.getIntrinsicWidth();
            mMinZoomScale = scale;
            matrix.postScale(scale, scale);



            iv.setImageMatrix(matrix);
        } else if (orientation == 1
        // && (float)draw.getIntrinsicHeight() >
        // (float)getWindowManager().getDefaultDisplay().getHeight()
        ) {
            scale = (float) getWindowManager().getDefaultDisplay().getHeight()
                    / (float) draw.getIntrinsicHeight();
            mMinZoomScale = scale;
            matrix.postScale(scale, scale);



            iv.setImageMatrix(matrix);
        }



        float transX = (float) getWindowManager().getDefaultDisplay()
                .getWidth()
                / 2
                - (float) (draw.getIntrinsicWidth() * scale)
                / 2;



        float transY = (float) getWindowManager().getDefaultDisplay()
                .getHeight()
                / 2
                - (float) (draw.getIntrinsicHeight() * scale)
                / 2



        ;
        matrix.postTranslate(transX, transY);
        iv.setImageMatrix(matrix);
    }



    @Override
    public float getMinZoomScale() {
        return mMinZoomScale;
    }



    @Override
    public boolean onTouchEvent(MotionEvent rawEvent) {
        if (gestureDetector.onTouchEvent(rawEvent))
            return true;



        ImageView view = (ImageView) findViewById(R.id.zero);
        switch (currentView) {
        case 0:
            view = (ImageView) findViewById(R.id.zero);
            break;
        case 1:
            view = (ImageView) findViewById(R.id.one);
            break;
        case 2:
            view = (ImageView) findViewById(R.id.two);
            break;
        }
        onTouchEvented(view, rawEvent);



        return true;
    }



    public void quit() {
        SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
                MODE_PRIVATE);



        SharedPreferences.Editor indexEditor = indexPrefs.edit();
        indexEditor.putInt("currentIndex", 0);
        indexEditor.commit();



        File settings = new File(DATA_FILE);
        settings.delete();
        finish();
        int pid = android.os.Process.myPid();
        android.os.Process.killProcess(pid);
        System.exit(0);
    }



}
And its right time to look on xml part.I have used animation also so add animation folder under res/anim..
slide_left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="80"/>
</set>

slide_left_out.xml 
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="80"/>
</set>



slide_right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="80"/>
</set>slide_right_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="80"/>
</set>

And add this in res/layout folder
mimetypes.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dp" >



    <com.nexbits.Imagegallary.RoundedImageView
        android:id="@+id/grid_item_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:scaleType="centerCrop" />



    <TextView
        android:id="@+id/grid_item_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dip"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:text="test string"
        android:textColor="#00ffff"
        android:textSize="10dip" />



</LinearLayout>
igmain.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:columnWidth="100dp"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth" >



</GridView>
imagemain.xml
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/flipper"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >



    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >



        <com.nexbits.Imagegallary.RoundedImageView
            android:id="@+id/zero"
            android:src="@drawable/ic_launcher"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="matrix" />
       
            
    </FrameLayout>
   



    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >



        <com.nexbits.Imagegallary.RoundedImageView
            android:id="@+id/one"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="matrix" />
    </FrameLayout>



    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >



      <com.nexbits.Imagegallary.RoundedImageView
            android:id="@+id/zero"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="matrix" />
   



        <com.nexbits.Imagegallary.RoundedImageView
            android:id="@+id/two"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="matrix" />
    </FrameLayout>



</ViewFlipper>
And finally add following xml in res/values folder
mimetypes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="image">
<item>bmp</item>
<item>cmx</item>
<item>cod</item>
<item>gif</item>
<item>ico</item>
<item>ief</item>
<item>jpe</item>
<item>jpeg</item>
<item>jpg</item>
<item>jfif</item>
<item>pbm</item>
<item>pgm</item>
<item>png</item>
<item>pnm</item>
<item>ppm</item>
<item>ras</item>
<item>rgb</item>
<item>svg</item>
<item>tif</item>
<item>tiff</item>
<item>xbm</item>
<item>xpm</item>
<item>xwd</item>
</string-array>
</resources>

 And finally output is as follows.........


































 












Comments

Post a Comment

Popular posts from this blog

Android O New Features Overview

This post assumes, you are an experienced developer who wants to get started with the latest version of Android. Android O is not a huge update to the OS and application framework like M but it still has many useful features for both developer and an user. Android O has focus on below areas. Notification redesigned Picture-in-Picture(PIP)  Visual adaption for different devices  Battery life improved Setting app reorganized Notification redesigned: Android O notification changes includes more easy and manageable way to manager your notification behavior and settings. It includes: Notification Channel: Notification channel allows you to create user customizable channel for each type of notification you wanna display. A single application can have multiple channel, a separate channel for each type of notification you wanna display. Having said this, you can create s separate channel for audio & image notification. User can disable specific notification channel instead

Java 8 Overview

Java 1.8 has introduced major features for the Java developers. It includes various upgrade to the Java programming, JVM, Tools and libraries. The main purpose of Java 1.8 release has been to simplify programming, utilize functional programming benefits and enable parallel programming/processing in Java programming language. Java 1.8 feature  Lambda(->) Expression Functional interfaces Default Methods in interface static method inside interface     Pre defined functional interfaces Predicate Function Consumer ::(Method reference and constructor reference by using double colon(::)operator) Stream API Date & Time API

Overview of how to develop native code with Android NDK:

  Create a jni directory and place native source code under $PROJECT/jni/... Create Android.mk directory and place it under $PROJECT/jni/... to describe source code to the NDK build system. Create Application.mk and place it under $PROJECT/jni/...to describe project in more details to the NDK build system.It is an optional. Finally need to build native source code by running '$NDK/ndk-build' from project directory or it's sub-directory. Android.mk An Android.mk file is a small build script that we write to describe sources to the NDK build system. It's syntax is like this... LOCAL_PATH:=$(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:=hello-jni LOCAL_SRC_FILES:=hello-jni.c include $(BUILD_SHARED_LIBRARY) NDK groups your sources into "modules", where each module can be one of the following: Static library Shared library We can write several module in a single 'Android.mk' or can write seve