Tuesday, January 7, 2014

GridView selected image zooming and swipe to next image

This example select any one image from GridView zooming selected image and swaipe to next image if tap to the selected image go back to the GridView.


activity_main.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <GridView
        android:id="@+id/gridView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnWidth="80dp"
        android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp" >
    </GridView>

    <ImageView
        android:id="@+id/expanded_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/app_name"
        android:visibility="invisible" />

</FrameLayout>

grid_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp" >

    <ImageView
        android:id="@+id/thumb"
        android:layout_width="72dp"
        android:layout_height="72dp"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/app_name" />

</RelativeLayout>


MainActivity.java


import android.os.Bundle;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;

public class MainActivity extends Activity {

private GridView gv;
private Animator mCurrentAnimator;
private int mShortAnimationDuration;
private int j = 0;
private final GestureDetector detector = new GestureDetector(new SwipeGestureDetector());
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

// Create Array thumbs resource id's:
private int thumb[] = { R.drawable.cupcake, R.drawable.donut,
R.drawable.eclair, R.drawable.froyo, R.drawable.gingerbread,
R.drawable.honeycomb, R.drawable.icecreamsandwich,
R.drawable.jellybean, R.drawable.cupcake, R.drawable.donut,
R.drawable.eclair, R.drawable.froyo, R.drawable.gingerbread,
R.drawable.honeycomb, R.drawable.icecreamsandwich,
R.drawable.jellybean };
private ImageView expandedImageView;

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

// Initialize the variables:
gv = (GridView) findViewById(R.id.gridView);

// Set an Adapter to the ListView
gv.setAdapter(new ImageAdapter(this));

// Set on item click listener to the ListView
gv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {

// Display the zoomed in image in full screen
j = pos;
zoomImageFromThumb(v, thumb[pos]);

}
});

// Set the Animation time form the android defaults
mShortAnimationDuration = getResources().getInteger(
android.R.integer.config_shortAnimTime);

}

// Create an Adapter Class extending the BaseAdapter
class ImageAdapter extends BaseAdapter {

private LayoutInflater layoutInflater;

public ImageAdapter(MainActivity activity) {
// TODO Auto-generated constructor stub
layoutInflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
// Set the count value to the total number of items in the Array
return thumb.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

// Inflate the item layout and set the views
View listItem = convertView;
int pos = position;
if (listItem == null) {
listItem = layoutInflater.inflate(R.layout.grid_item, null);
}

// Initialize the views in the layout
ImageView iv = (ImageView) listItem.findViewById(R.id.thumb);

// Set the views in the layout
iv.setBackgroundResource(thumb[pos]);

return listItem;
}

}

private void zoomImageFromThumb(final View thumbView, int imageResId) {
// If there's an animation in progress, cancel it immediately and
// proceed with this one.
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}

// Load the high-resolution "zoomed-in" image.
expandedImageView = (ImageView) findViewById(R.id.expanded_image);
expandedImageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (detector.onTouchEvent(event))
                    return true;
                else
                    return false;
            }
        });
expandedImageView.setImageResource(imageResId);

// Calculate the starting and ending bounds for the zoomed-in image.
// This step
// involves lots of math. Yay, math.
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();

// The start bounds are the global visible rectangle of the thumbnail,
// and the
// final bounds are the global visible rectangle of the container view.
// Also
// set the container view's offset as the origin for the bounds, since
// that's
// the origin for the positioning animation properties (X, Y).
thumbView.getGlobalVisibleRect(startBounds);
findViewById(R.id.container).getGlobalVisibleRect(finalBounds,
globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);

// Adjust the start bounds to be the same aspect ratio as the final
// bounds using the
// "center crop" technique. This prevents undesirable stretching during
// the animation.
// Also calculate the start scaling factor (the end scaling factor is
// always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds
.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}

// Hide the thumbnail and show the zoomed-in view. When the animation
// begins,
// it will position the zoomed-in view in the place of the thumbnail.
thumbView.setAlpha(0f);
expandedImageView.setVisibility(View.VISIBLE);

// Set the pivot point for SCALE_X and SCALE_Y transformations to the
// top-left corner of
// the zoomed-in view (the default is the center of the view).
expandedImageView.setPivotX(0f);
expandedImageView.setPivotY(0f);

// Construct and run the parallel animation of the four translation and
// scale properties
// (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
set.play(
ObjectAnimator.ofFloat(expandedImageView, View.X,
startBounds.left, finalBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
startBounds.top, finalBounds.top))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
startScale, 1f))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y,
startScale, 1f));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}

@Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;

// Upon clicking the zoomed-in image, it should zoom back down to the
// original bounds
// and show the thumbnail instead of the expanded image.
final float startScaleFinal = startScale;
expandedImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}

// Animate the four positioning/sizing properties in parallel,
// back to their
// original values.
AnimatorSet set = new AnimatorSet();
set.play(
ObjectAnimator.ofFloat(expandedImageView, View.X,
startBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
startBounds.top))
.with(ObjectAnimator.ofFloat(expandedImageView,
View.SCALE_X, startScaleFinal))
.with(ObjectAnimator.ofFloat(expandedImageView,
View.SCALE_Y, startScaleFinal));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}

@Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
}
});
}
private class SwipeGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            try {
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                   if(thumb.length>j)
                    {
                        j++;

                        if(j < thumb.length)
                        {                           
                        expandedImageView.setImageResource(thumb[j]);
                            return true;
                        }
                        else
                        {
                            j = 0;
                            expandedImageView.setImageResource(thumb[j]);
                            return true;
                        }

                    }
                }
                else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {


                    if(j>0)
                    {
                        j--;
                        expandedImageView.setImageResource(thumb[j]);
                        return true;

                    }
                    else
                    {
                    j = thumb.length-1;
                    expandedImageView.setImageResource(thumb[j]);
                        return true;
                    }
                }
            }
                catch (Exception e) {
                    e.printStackTrace();
                }
                return false;
        }
    }

}




Wednesday, October 9, 2013

Add custom title on ActionBar in android

title_latout.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:textSize="11sp"
        android:id="@+id/logout_btn"
        android:text="Logout" />

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/title_text"
        android:layout_toRightOf="@+id/logout_btn"
        android:layout_centerInParent="true"
        android:layout_toLeftOf="@+id/setting_btn"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:text="DoMyExpenses"/>

    <ImageButton android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="5dp"
        android:background="@android:drawable/ic_menu_compass"
        android:id="@+id/setting_btn"/>


</RelativeLayout>



        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setIcon(android.R.color.transparent);
        actionBar.setDisplayShowCustomEnabled(true);
        View customTitle = getLayoutInflater().inflate(R.layout.title_layout, null);
        title_text = (TextView)customTitle.findViewById(R.id.title_text);
        title_text.setText("Saved Expenses");
        actionBar.setCustomView(customTitle);

Saturday, September 21, 2013

Google map release key in android

Generally there are two keys debug key and release key. while signing app, you want to use release key. For that you want to compare that with signed apk

Step 1:
Say for example your apk name is A and you are signing and creating a keystore for A.apk ie A.keystore will be created in some drive location.Let's consider it in E drive.

step 2:
Now locate to jdk in C drive(Considering for windows and assigning C drive)
C:\Program Files\Java\jdk1.7.0\bin>keytool -list -v -keystore E:\A.keystore -alias A
So it will create SHA-1 fingure print

copy and paste that in google map console, it wll generate a key.use it in maps.

Tuesday, April 30, 2013

Eraser in Android View


public class FingerText extends Activity
    implements ColorPickerDialog.OnColorChangedListener {    

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

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    //this is the line that sets the initial pen color
    mPaint.setColor(inkColor);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(2);
}



private Paint       mPaint;
private Bitmap      mBitmap;
private boolean             inkChosen;
private int bgColor = 0xFFFFFFFF;  //set initial bg color var to white
private int inkColor =  0xFF000000; //set initial ink color var to black

public void colorChanged(int color) {
    //This is the implementation of the interface from colorpickerdialog.java

    if (inkChosen){
            mPaint.setColor(color);
            inkColor = color;
    }
    else {
            mBitmap.eraseColor  (color);
            bgColor = color;
            //set the color to the user's last ink color choice
            mPaint.setColor(inkColor); 
    }



}

public class MyView extends View {



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

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

        mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);

        //this sets the bg color for the bitmap
        mBitmap.eraseColor  (bgColor);
        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //this is the line that changes the bg color in the initial canvas
            canvas.drawColor(bgColor);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);
    }

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

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }
    private void touch_up() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

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

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

private static final int BG_COLOR_ID = Menu.FIRST;
private static final int INK_MENU_ID = Menu.FIRST + 1;
private static final int CLEAR_MENU_ID = Menu.FIRST + 2;
private static final int ERASER_MENU_ID = Menu.FIRST + 3;
private static final int SEND_MENU_ID = Menu.FIRST + 4;

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

    menu.add(0, BG_COLOR_ID, 0, "Background Color").setShortcut('3', 'b');
    menu.add(0, INK_MENU_ID, 0, "Ink Color").setShortcut('4', 'c');
    menu.add(0, CLEAR_MENU_ID, 0, "Clear All").setShortcut('5', 'e');
    menu.add(0, ERASER_MENU_ID, 0, "Eraser").setShortcut('6', 'x');
    menu.add(0, SEND_MENU_ID, 0, "Send").setShortcut('7', 's');

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

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

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

    switch (item.getItemId()) {

            case BG_COLOR_ID:
                    new ColorPickerDialog(this, this, mPaint.getColor()).show();
                    inkChosen = false;
                    return true;
        case INK_MENU_ID:
            new ColorPickerDialog(this, this, mPaint.getColor()).show();
            //remember the user's last ink choice color so we can revert after eraser
            //to background color change -- otherwise ink is last bg color
            inkColor = mPaint.getColor();
            inkChosen = true;
            return true;
        case CLEAR_MENU_ID:
            mBitmap.eraseColor  (bgColor);
            return true;
        case ERASER_MENU_ID:
            //set pen color to bg color for 'erasing'
            mPaint.setColor(bgColor);
            return true;
        case SEND_MENU_ID:
                    /* TODO need to decide whether to save image locally
                     * and how to make it available if so. really only need to
                     * save if we want to let users view later, or pick a
                     * previous message to send again 
                     */

                    // this try-catch block creates a private file and an
                    // inputstream pointing to it for reading
            FileInputStream ifs;
                            try {
                                    FileOutputStream fs = openFileOutput("message_image", Context.MODE_PRIVATE);
                                    mBitmap.compress(CompressFormat.PNG, 100, fs);
                                    ifs = openFileInput("message_image");
                            } catch (FileNotFoundException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                    return true;
                            }
                                    // inserts file pointed to by ifs into image gallery
                            String url = Images.Media.insertImage(getContentResolver(),
                                    BitmapFactory.decodeStream(ifs),
                                    "Message image1", "Message image");

                                    // alternative: inserts mBitmap into image gallery
/*              String url = Images.Media.insertImage(getContentResolver(),
                                mBitmap, "Message image1", "Message image");
*/
                                    // creates the Intent to open the messaging app
                                    // with the image at url attached
            Intent sendIntent = new Intent(Intent.ACTION_SEND); 
            sendIntent.putExtra("sms_body", "Message created using FingerText"); 
            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
            sendIntent.setType("image/png");
            startActivity(sendIntent);
                    /* TODO delete the image from the content provider
                     * following line deletes the image, but too soon!
                     */
//              getContentResolver().delete(Uri.parse(url), null, null);


            //this resets canvas after send   
            //could also reset to last user settings w/o var resets
            bgColor = 0xFFFFFFFF;  //set bg color var back to white
            inkColor =  0xFF000000; //set ink color var back to black
            mBitmap.eraseColor  (bgColor);
            return true;
    }
    return super.onOptionsItemSelected(item);
}