Dialogfragment dynamic grow animation on image item click - java

I created the recyclerview with grid layout manager. When any one clicks on the image thumbnail the image should be expanded to full screen in Dialogfragment which has view pager with the animation from the thumb clicked.
I have tried the different solution but not worked. The animation directly applied from the styles working but how to define the dynamic runtime animation.
I had tried the following but not working exactly.
Any idea on how to achieve this thing??
MediaFragment.java
#Override
public void onItemClick(View v, int position) {
switch (v.getId()) {
case R.id.llItemContainer:
Bundle bundle = new Bundle();
bundle.putInt(Constant.KEY_CURRENT_ITEM, position);
dialogMediaProfileFragment = new DialogMediaProfileFragment();
dialogMediaProfileFragment.setArguments(bundle);
dialogMediaProfileFragment.show(getFragmentManager(), TAG);
zoomImageFromThumb(v).start();
break;
}
}
private Animator zoomImageFromThumb(final View thumbView) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
startBounds = new Rect();
finalBounds = new Rect();
Point globalOffset = new Point();
thumbView.getGlobalVisibleRect(startBounds);
rvMediaPost.getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
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;
}
setAlpha(thumbView, 1f);
//This shows the nullpointer exception
/*setPivotX(dialogMediaProfileFragment.getView(), 0f);
setPivotY(dialogMediaProfileFragment.getView(), 0f);*/
AnimatorSet set = new AnimatorSet();
set.play(
ObjectAnimator.ofFloat(dialogMediaProfileFragment, "translationX",
startBounds.left, finalBounds.left))
.with(ObjectAnimator.ofFloat(dialogMediaProfileFragment, "translationY",
startBounds.top, finalBounds.top))
.with(ObjectAnimator.ofFloat(dialogMediaProfileFragment, "scaleX",
startScale, 1f))
.with(ObjectAnimator.ofFloat(dialogMediaProfileFragment, "scaleY",
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;
}
});
return mCurrentAnimator = set;
}
private void setAlpha(View view, float alpha) {
view.setAlpha(alpha);
}
private void setPivotX(View view, float x) {
view.setPivotX(x);
}
private void setPivotY(View view, float y) {
view.setPivotY(y);
}

#Jaymin Panchal,
You have to implement customize Android Activity Transition animation.
Also you can refer this code snippet for more on about your requirement.

Related

android how to recycle image before loading a new one

I have a out of memory problem here in which i have full screen images being displayed. I want to show images in full screen and I have two buttons to cycle through them to the left or to the right. How can i have the past images be recycled before showing the next to prevent the out of memory exception? or is there an even better way to do so?
here is my class in which i view the image.
public class ImageViewActivity extends Activity
{
private Button btnHome;
private Button btnBack;
private ImageButton btnLeft;
private ImageButton btnRight;
ImageView imageView;
RelativeLayout layout;
int height;
int width;
Bitmap bitmap;
String[] imagesPath;
int position;
// These matrices will be used to move and zoom image
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 mid = new PointF();
float oldDist = 1f;
String savedItemClicked;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.imageview_activity);
btnHome = (Button) findViewById(R.id.btnHome);
btnBack = (Button) findViewById(R.id.btnBack);
btnLeft = (ImageButton) findViewById(R.id.leftArrow);
btnRight = (ImageButton) findViewById(R.id.rightArrow);
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
width = displayMetrics.widthPixels;
imagesPath = getIntent().getStringExtra("IMAGES").split("\\|");
position = getIntent().getIntExtra("POSITION", 0);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
btnLeft.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
if (position == 0)
position = 5;
else
position--;
RectF imageRectF = new RectF(0, 0, width, height);
RectF viewRectF = new RectF(0, 0, width, height);
matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
ImageView imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
imageView.setImageMatrix(matrix);
}
});
btnRight.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
if (position == 5)
position = 0;
else
position++;
RectF imageRectF = new RectF(0, 0, width, height);
RectF viewRectF = new RectF(0, 0, width, height);
matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
ImageView imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
imageView.setImageMatrix(matrix);
}
});
btnHome.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
Intent ActivitySwitch = new Intent(getApplicationContext(), MainMenuActivity.class);
startActivity(ActivitySwitch);
}
});
btnBack.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
Intent ActivitySwitch = new Intent(getApplicationContext(), AddClientActivity.class);
startActivity(ActivitySwitch);
}
});
imageView.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
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());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
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);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
});
}
private void dumpEvent(MotionEvent 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("]");
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float)Math.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
thank you for any input and if you need any additional information please feel free to ask!
I would either scale down the image or consider using the Picasso image loading library: http://square.github.io/picasso/
It is also really simply to use and prevents a lot Out of Memory Exceptions.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
it was a lot simpler then i first imagined. i simply added this
bitmap.recycle();
before i declared my bitmap to the new image.

How to stop swipe at some point in ItemTouchHelpers?

I need to swipe an item at the beginning, or did a full swipe, or stopped in current point. As in the Yandex mail. I was tring to do setLeft(dx) and setRight(dx) but that's not what I need
I have class
ItemTouchHelperCallback extends ItemTouchHelper.Callback
and inside i override method
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
View itemView = viewHolder.itemView;
// not sure why, but this method get's called for viewholder that are already swiped away
if (viewHolder.getAdapterPosition() == -1) {
// not interested in those
return;
}
float height = (float) itemView.getBottom() - (float) itemView.getTop();
float width = height / 3;
float temdX=0;
Bitmap icon;
if(dX > 0 || lastdX>0){
//try stop item while back in dx=0, but workin only while i debug
if(lastdX>=100 && dX==0 &&lastdX!=0 &&lastdX!=-720)
{
dX=100;
isCurrentlyActive=true;
}
lastdX=dX;
itemView.setLeft((int) dX);
p.setColor(Color.GREEN);
RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_y);
RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width, (float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
c.drawBitmap(icon, null, icon_dest, p);
} else if(lastdX<0 || dX<0) {
if(lastdX<=-100 && dX==0 &&lastdX!=0 &&lastdX!=720)
{
dX=-100;
//itemView.setTranslationX(-200);
isCurrentlyActive=true;
}
lastdX=dX;
itemView.setRight((int)(dX));
p.setColor(Color.RED);
RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom());
c.drawRect(background,p);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_x);
RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width, (float) itemView.getRight() - width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,icon_dest,p);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
I needed to do something similar and at the beginning I also thought to use the callbacks provided in the ItemTouchHelper. It turned out it's not the right approach.
If you want to stop (or in general to control) the translation of the view during the swipe, you need to be able to modify and save the value of the displacement dX. If you use the ItemTouchHelper, this value is controlled outside the available callbacks.
The solution for me was the implementation of the swipe with a custom touchListener, attached in the view holder of the recycler view. You can find an example of the basic implementation here. In case you need to consider the click on the item, remember you need to implement this in the touchListener as well.
I hope this is somehow helpful.
EDIT
Here a snippet of a custom ItemTouchListener. The listener is simplified and shows only code to handle the translation on the view during swipe. In order to stop swipe, just implement limit logic on translationX under ACTION_MOVE.
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
public class ItemTouchListener implements View.OnTouchListener {
private int mSlop;
private View mView;
private float mDownX, mDownY;
private boolean mSwiping;
private int mSwipingSlop;
private VelocityTracker mVelocityTracker;
private float mTranslationX;
public ItemTouchListener(View view) {
ViewConfiguration vc = ViewConfiguration.get(view.getContext());
mSlop = vc.getScaledTouchSlop();
mView = view;
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// offset because the view is translated during swipe
motionEvent.offsetLocation(mTranslationX, 0);
switch (motionEvent.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
mDownX = motionEvent.getRawX();
mDownY = motionEvent.getRawY();
return true;
}
case MotionEvent.ACTION_UP: {
// if needed, implement part of limit swipe logic also here
if (mVelocityTracker == null) {
break;
}
mVelocityTracker.addMovement(motionEvent);
mVelocityTracker.computeCurrentVelocity(1000);
mVelocityTracker.recycle();
mVelocityTracker = null;
mTranslationX = 0;
mDownX = 0;
mDownY = 0;
mSwiping = false;
break;
}
case MotionEvent.ACTION_CANCEL: {
if (mVelocityTracker == null) {
break;
}
mVelocityTracker.recycle();
mVelocityTracker = null;
mTranslationX = 0;
mDownX = 0;
mDownY = 0;
mSwiping = false;
break;
}
case MotionEvent.ACTION_MOVE: {
if (mVelocityTracker == null) {
break;
}
mVelocityTracker.addMovement(motionEvent);
float deltaX = motionEvent.getRawX() - mDownX;
float deltaY = motionEvent.getRawY() - mDownY;
if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
mSwiping = true;
mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
// cancel view's touch
MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
(motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
cancelEvent.recycle();
}
if (mSwiping) {
// limit deltaX here: this will keep the swipe up to desired point
mTranslationX = deltaX;
mView.setTranslationX(deltaX - mSwipingSlop);
return true;
}
break;
}
}
return false;
}
}

Android animate layout changed weight height

I have two layouts
[layout 1]
[layout 2]
with equal weight. When I scroll down, I change weight of [layout 1] and [layout 2].
I want to know how is it possible to animate layout change weight.
I've tried
android:animateLayoutChanges="true"
and
LayoutTransition transition = new LayoutTransition();
mapLayout.setLayoutTransition(transition);`
but none of this methods works.
You can do something similar to this resize animation.
public class ResizeAnimation extends Animation
{
int _startWidth;
int _targetWidth;
View _view;
private int _targetHeight;
private int _startHeight;
public ResizeAnimation(View view, int targetWidth, int targetHeight)
{
_view = view;
_targetWidth = targetWidth;
_startWidth = view.getWidth();
_targetHeight = targetHeight;
_startHeight = view.getMeasuredHeight();
setFillAfter(true);
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
int newWidth = (int) (_startWidth + (_targetWidth - _startWidth) * interpolatedTime);
int newHeight = (int) (_startHeight + (_targetHeight - _startHeight) * interpolatedTime);
_view.getLayoutParams().width = newWidth;
_view.getLayoutParams().height = newHeight;
_view.requestLayout();
}
#Override
public boolean willChangeBounds()
{
return true;
}
}
private class ExpandAnimation extends Animation {
private float mStartWeight;
private float mDeltaWeight;
private LinearLayout mContent;
private boolean direction;// true - up; false - down
public ExpandAnimation(LinearLayout content, float startWeight,
float endWeight) {
mStartWeight = startWeight;
mDeltaWeight = endWeight - startWeight;
mContent = content;
}
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContent
.getLayoutParams();
mStartWeight = lp.weight;
lp.weight = (mStartWeight + (mDeltaWeight * interpolatedTime));
mContent.setLayoutParams(lp);
}
#Override
public boolean willChangeBounds() {
return true;
}
}

How to animate the width and height of a Layout?

I have a LinearLayout which is expanded to full screen by hiding all other layouts and views on onClick. There is a Relativelayout above LinearLayout
I want to apply custom animation on this. The size should should increase slowly (like in 500 milli seconds).
But I doubt is it possible? Thanks.
Here is what I am doing onClick:
private void expandView (int viewId) {
RelativeLayout relativeLayout = (RelativeLayout) ((LinearLayout) view.findViewById(viewId)).getParent();
ViewGroup.MarginLayoutParams rlMargin = (ViewGroup.MarginLayoutParams) relativeLayout.getLayoutParams();
rlMargin.setMargins(0, 0, 0, 0);
relativeLayout.setLayoutParams(rlMargin);
LinearLayout linearLayout = (LinearLayout) relativeLayout.getParent();
hideAllLinearLayoutExcept(linearLayout.getId());
hideAllTilesExcept(viewId);
}
viewId is the id of the LinearLayout I am clicking. This function is called from onClick()
Sure that is possible.
Simply write your own custom-animation and modify the LayoutParams of your animated view.
In this example, the animation animates the height of the animated View. Of course, animating the width is also possible.
This is how it could look like:
public class ResizeAnimation extends Animation {
private int startHeight;
private int deltaHeight; // distance between start and end height
private View view;
/**
* constructor, do not forget to use the setParams(int, int) method before
* starting the animation
* #param v
*/
public ResizeAnimation (View v) {
this.view = v;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height = (int) (startHeight + deltaHeight * interpolatedTime);
view.requestLayout();
}
/**
* set the starting and ending height for the resize animation
* starting height is usually the views current height, the end height is the height
* we want to reach after the animation is completed
* #param start height in pixels
* #param end height in pixels
*/
public void setParams(int start, int end) {
this.startHeight = start;
deltaHeight = end - startHeight;
}
/**
* set the duration for the hideshowanimation
*/
#Override
public void setDuration(long durationMillis) {
super.setDuration(durationMillis);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
In code, create a new Animation and apply it to the RelativeLayout that you want to animate:
RelativeLayout relativeLayout = (RelativeLayout) ((LinearLayout) view.findViewById(viewId)).getParent();
// getting the layoutparams might differ in your application, it depends on the parent layout
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();
ResizeAnimation a = new ResizeAnimation(relativeLayout);
a.setDuration(500);
// set the starting height (the current height) and the new height that the view should have after the animation
a.setParams(lp.height, newHeight);
relativeLayout.startAnimation(a);
I was looking for this for hours and Philipp Jahoda's answer was the perfect one since it can be added to an AnimationSet as well. I made a couple of small modifications to support a more similar constructor to the default animation class (except for the View parameter) and to support the "fillEnabled" property.
public class ResizeAnimation extends Animation
{
private int startWidth;
private int deltaWidth; // distance between start and end height
private int startHeight;
private int deltaHeight;
private int originalWidth;
private int originalHeight;
private View view;
private boolean fillEnabled = false;
public ResizeAnimation(View v, int startW, int endW, int startH, int endH)
{
view = v;
startWidth = startW;
deltaWidth = endW - startW;
startHeight = startH;
deltaHeight = endH - startH;
originalHeight = v.getHeight();
originalWidth = v.getWidth();
}
#Override
public void setFillEnabled(boolean enabled)
{
fillEnabled = enabled;
super.setFillEnabled(enabled);
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
if(interpolatedTime == 1.0 && !fillEnabled)
{
view.getLayoutParams().height = originalHeight;
view.getLayoutParams().width = originalWidth;
}
else
{
if(deltaHeight != 0)
view.getLayoutParams().height = (int) (startHeight + deltaHeight * interpolatedTime);
if(deltaWidth != 0)
view.getLayoutParams().width = (int) (startWidth + deltaWidth * interpolatedTime);
}
view.requestLayout();
}
}
Here's a simplified, more general (any parameter of layout), Xamarin version.
public class SizeAnimation : Animation
{
private int _newValue;
private int _initialValue;
private string _property;
private object _target;
private View _view;
public SizeAnimation (View view, string property, int newValue)
{
_view = view;
_property = property;
_newValue = newValue;
_target = view.LayoutParameters;
// View measure is generally an enum of wrap_content / fill_parent
// we need to make the measure explicit
if (property == "Width" || property == "Height")
{
view.Measure ((int)MeasureSpecMode.Unspecified, (int)MeasureSpecMode.Unspecified);
var unmeasuredValue = (int)view.GetType().GetProperty(property).GetValue(view);
_initialValue = unmeasuredValue < 1
? (int) view.GetType().GetProperty("Measured" + _property).GetValue(view)
: unmeasuredValue;
view.LayoutParameters.GetType().GetProperty(property).SetValue(view.LayoutParameters,_initialValue);
} else
{
_initialValue = (int) _target.GetType ().GetProperty (property).GetValue(_target);
}
}
protected override void ApplyTransformation(float interpolatedTime, Transformation t)
{
_target.GetType().GetProperty(_property).SetValue(_target, (int)(_initialValue + (_newValue - _initialValue) * interpolatedTime));
_view.RequestLayout();
}
public override bool WillChangeBounds()
{
return true;
}
}
Usage:
var property = "Width";
var value = 120;
var animation = new SizeAnimation(myView, property, value);
animation.Duration = 2000;
animation.Interpolator = (new LinearInterpolator());
myView.StartAnimation(animation);
"Theorically" working, not fully tested.
I worked with the answer by Philipp Jahoda. Here is an implementation that works for both expand and collapse animations based on the start and end values we pass. Hope it helps.
https://gist.github.com/rahulrvp/dcccd1b78cd09b31a024

Unable to zoom in the bus route map

i have a bus route map as an image.
using the zoom controller the image is zooming out but not zooming in
please look at my code and let me know the change to be done make it working..
i am developing my app on Gingerbread i.e API 10
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.ZoomControls;
public class Busmaps extends Activity {
ImageView img;
ZoomControls zoom;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.busmaps);
img = (ImageView) findViewById(R.id.imageViewmaps1);
zoom = (ZoomControls) findViewById(R.id.zoomControls1);
zoom.setOnZoomInClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int w = img.getWidth();
int h = img.getHeight();
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(w + 50, h + 50);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
img.setLayoutParams(params);
}
});
zoom.setOnZoomOutClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int w = img.getWidth();
int h = img.getHeight();
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(w - 50, h - 50);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
img.setLayoutParams(params);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.bus_map_zoom, menu);
return true;
}
}
my xml says for bus route image:-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageViewmaps1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/map" />
<ZoomControls
android:id="#+id/zoomControls1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
how should i make my zoom control working for both Zoom in and Zoom out.
Please replace your Zoom in and ZoomOut listener with the following:
zoom.setOnZoomInClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
float x = img.getScaleX();
float y = img.getScaleY();
img.setScaleX((float) (x+1));
img.setScaleY((float) (y+1));
}
});
zoom.setOnZoomOutClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
float x = img.getScaleX();
float y = img.getScaleY();
img.setScaleX((float) (x-1));
img.setScaleY((float) (y-1));
}
});
}
Alternate option is to load the image in the Web view which has build in zoom controller.
As follows:
String page = "<html><body><center><img src=\""+path to your image+"\"/></center></body></html>";
webView.loadDataWithBaseURL("fake",page, "text/html", "UTF-8","");
If you dont want to use the build in web view zoom controller then you can just place your own buttons and apply zoom in and zoom out on web view as follows:
webView.setInitialScale(ZOOM_LEVEL);
public class Busmap extends Activity implements OnTouchListener
{
private static final String TAG = "Touch";
#SuppressWarnings("unused")
private static final float MIN_ZOOM = 1f,MAX_ZOOM = 1f;
// These matrices will be used to scale points of the image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// The 3 states (events) which the user is trying to perform
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// these PointF objects are used to record the point(s) the user is touching
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.busmaps);
ImageView view = (ImageView) findViewById(R.id.imageViewmaps1);
view.setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale;
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN: // first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG"); // write to LogCat
mode = DRAG;
break;
case MotionEvent.ACTION_UP: // first finger lifted
case MotionEvent.ACTION_POINTER_UP: // second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_POINTER_DOWN: // first and second finger down
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 5f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG)
{
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix of points
}
else if (mode == ZOOM)
{
// pinch zooming
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 5f)
{
matrix.set(savedMatrix);
scale = newDist / oldDist; // setting the scaling of the
// matrix...if scale > 1 means
// zoom in...if scale < 1 means
// zoom out
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix); // display the transformation on screen
return true; // indicate event was handled
}
private float spacing(MotionEvent event)
{
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event)
{
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}

Categories