Zooming image in android - android

I want to add an image in my application which is like a road map image.
I want to add zooming features to this image as well as horizontal scrolling when the image is zoomed.
I have written some code but it allows only zooming and not scrolling.
Code:
public class Zoom extends View {
private Drawable image;
private int zoomControler=20;
public Zoom(Context context)
{
super(context);
image=context.getResources().getDrawable(R.drawable.boothmap);
setFocusable(true);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
image.setBounds((getWidth()/2)-zoomControler, (getHeight()/2)-zoomControler, (getWidth()/2)+zoomControler, (getHeight()/2)+zoomControler);
image.draw(canvas);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_DPAD_UP)// zoom in
zoomControler+=10;
if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN) // zoom out
zoomControler-=10;
if(zoomControler<10)
zoomControler=10;
invalidate();
return true;
}
}
Can you help me solving this problem. Is my code proper so far or do you have any better code?

what worked for me is : just add built in zoom controls to webview and then call its loadDataWithBaseURL method.
webview.getSettings().setBuiltInZoomControls(true);
webview.loadDataWithBaseURL("file:///android_asset/", "<img src='file:///android_res/drawable/example.png' />", "text/html", "utf-8", null);

Look at this post :
How can I get zoom functionality for images?
You have to use webview.loadUrl("file://...") to load your image
and activate zoom option

You'll get very bad results by trying to handle multi-touch with loadUrl. Try this tutorial, It provides the best source code I found to do that. If you tweak a bit the code you can make it work on 2.1 as well.

You are modifying the image bounds instead of modofying the view bounds. Try modifying the view height and width. You should be able to scroll then.
Will need to override onMeasure() method and set setMeasuredDimension as current height and width. Maintain the height and width as members.
EDIT:
class YourView extends View {
static Bitmap mOrignalBitmap = null; // check n load in constructor.
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(mWidth,mHeight);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect src = new Rect(0,0, originalWidth, originalHeight);
Rect dst = new Rect(viewLeft, viewTop, viewRight, viewBottom);
canvas.drawBitmap(mOrignalBitmap , src, dst, null);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_DPAD_UP)// zoom in
zoomControler+=10;
if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN) // zoom out
zoomControler-=10;
if(zoomControler<10)
zoomControler=10;
mWidth = //set view width with zoom
mHeight = // set view height with zoom.
requestLayout();
return true;
}
}

Related

Photoview ondraw

I am kind of new to the onDraw so i don't know how to go around this problem.
I want to draw a image at this location (just so i can try the rest myself). These locations are off the ontap and * the drawables width and height. This code is in a class that extends photoview.
The problem is this resource is not being displayed, i also tried to use on a drawcirlce example that also didnt display. I have also attached that below.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap markerBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.markerformap);
canvas.drawBitmap(markerBitmap, 2000, 5000, new Paint());
}
Draw circle example
canvas.drawCircle(2000, 5000,300, new Paint());
The onTouch Listener
#Override
public boolean onTouch(View v, MotionEvent event) {
if(y != event.getY() && x != event.getX()){
x = event.getX();
y = event.getY();
return true;
}
return false;
}

How to check if imageview is currently zoomed or not in android?

i am zooming an image view on double tap to some certain points. on double tap event it zooms in perfectly but i want to implement the functionality of zoom out too that when user double taps the image is zoomed but when he double tap again the zoomed image must go back to original size
how this can be done? Any help will be appreciated
Here is my code
ImageView iv;
private Matrix matrix = new Matrix();
Bitmap bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(
getResources(), R.drawable.demoimg), size.x, size.y, true);
iv.setImageBitmap(bmp);
original_matrix = iv.getImageMatrix();
iv.setOnTouchListener(new View.OnTouchListener() {
private GestureDetector gestureDetector = new GestureDetector(SecondActivity.this, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDoubleTap(MotionEvent e) {
float scalefactor = Math.max(1.1f, Math.min(3.0f, 4.0f));
float x = e.getX();
float y = e.getY();
matrix.setScale(scalefactor, scalefactor, x, y);
iv.setImageMatrix(matrix);
return super.onDoubleTap(e);
}
});
#Override
public boolean onTouch(View v, MotionEvent event) {
/* Toast.makeText(getApplicationContext(), "On Touch Event Called",
Toast.LENGTH_LONG).show();*/
gestureDetector.onTouchEvent(event);
return true;
}
});
The best practice is to Extend the imageView and make your customImageView.
In your customImageView keep the original size of your image and the track of image current state (zoomed in/out) then in your xml use your customImageView instead of android imageView .
You can put your zoom method in your customImageView. Then you have a customImageView which know how to zoom in, get back to the original size and its current state.

How disable scroll movement when i move a bitmap?

I want move a bitmap in the screen, but i can do it only horizontally, because if I do it vertically, the scroll of the view start and the movement of the bitmap disappears. I have
public boolean onTouchEvent(MotionEvent event)
method where in case MOVE I change the X and Y of the bitmap. Then in onDraw() method I paint the bitmap. The scroll are in xml. Inside of it are a layout and inside a View.
I would like when I touch, in case DOWN, if I touch the bitmap, disable the scroll, but I is in other place no.
that is the resume of the code
public class Table extends ScrollView{
private static Integer srcX = 0, srcY = 0;
public Table(Context context) {
super(context);
setWillNotDraw(false);
setVerticalScrollBarEnabled(true);
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=1; i<= Paint_Table.num_players; i++)
canvas.drawBitmap(bitmap, X, Y, null);
}
#SuppressLint("ClickableViewAccessibility") #Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
if (youTouchBitmap) {
srcX = x;
srcY = y;
}
break;
case MotionEvent.ACTION_MOVE:
if (srcX !=0 && srcY != 0) {
X=x;
Y=y;
invalidate();
}
break;
}
return true;
}
}
Can someone help me?
Thanks and regards.
since i dont see code ive find some link might help you:
How to disable and enable the scrolling on android ScrollView?
in the link you can see in the answers a code that is custom scroll view its work on flag.
you can choose when the scroll will work ot not.
hope i helpd :)

Set custom anchor when dragging a View

I am using Android Drag&Drop API and am trying to set the anchor of the drag shadow to the point where the touch was made in the View. The dafault behavior is to have the anchor the middle of the View.
I did some research and it seems this can be done by overriding the onProvideShadowMetrics (Point shadowSize, Point shadowTouchPoint) method in the DragShadowBuilder class. From what I understood, if I change the x,y coordinates of shadowTouchPoint it should modify the coordinates of the drag anchor.
What I did was to extend the DragShadowBuilder class like so:
class EventDragShadowBuilder extends DragShadowBuilder {
int touchPointXCoord, touchPointYCoord;
public EventDragShadowBuilder() {
super();
}
public EventDragShadowBuilder(View view, int touchPointXCoord,
int touchPointYCoord) {
super(view);
this.touchPointXCoord = touchPointXCoord;
this.touchPointYCoord = touchPointYCoord;
}
#Override
public void onProvideShadowMetrics(Point shadowSize,
Point shadowTouchPoint) {
shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
}
}
In the Fragment where I use drag&drop I created two listeners to start a drag event for a View:
mEventLongClickListener = new OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
EventDragShadowBuilder shadowBuilder = new EventDragShadowBuilder(
view, mEventTouchXCoord, mEventTouchYCoord);
view.startDrag(null, shadowBuilder, view, 0);
return true;
}
};
// We need this listener in order to get the corect coordinates for the
// drag shadow
mEventTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
mEventTouchXCoord = (int) event.getX();
mEventTouchYCoord = (int) event.getY();
break;
}
}
return false;
}
};
And I set the tow listeners:
itemView.setOnLongClickListener(mEventLongClickListener);
itemView.setOnTouchListener(mEventTouchListener);
Everything ok up to here. But when I test the app and start the drag process, the drag shadow is centered under the touch point. So it uses the default behavior. I tried debugging and I see that mEventTouchXCoord and mEventTouchYCoord are set correctly. The method shadowTouchPoint.set(touchPointXCoord, touchPointYCoord); gets the correct coordinates but still it centers the shadow.
I don't know what I'm doing wrong. Maybe I misunderstood the API. Any help with or hint would be much appreciated.
Ok, so like Scoup said the problem was in the onProvideShadowMetrics() method. The fact is, if I remove the super constructor, super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);, it will not show the drag shadow anymore.
Taking a closer look at the API method this is what I found:
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
final View view = mView.get();
if (view != null) {
shadowSize.set(view.getWidth(), view.getHeight());
shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
} else {
Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
}
}
So indeed, it resets the shadowTouchPoint to the middle of the dragged View. But it also initializes the drag shadow to the correct dimensions. While I want the drag shadow dimensions to be set correctly I don't want to reset shadowTouchPoint.
The easiest way to acheive this is to call the super constructor before initializing the shadowTouchPoint with the custom values, like so:
#Override
public void onProvideShadowMetrics(Point shadowSize,
Point shadowTouchPoint) {
super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
shadowTouchPoint.set(touchPointXCoord, touchPointYCoord);
}
Another solution is to deal with the drag shadow View yourself and skip the super constructor altogether. I will get back with a detailed update.
I guess the problem is this line super.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
You already changed the value of shadowTouchPoint in shadowTouchPoint.set(touchPointXCoord, touchPointYCoord); but when call the super, you are passing the shadowTouchPoint that is replaced with the "super" default method, and the default behavior is center the shadowTouchPoint.
So, just remove this line.

ImageView click best practice

I am a newbie in Andoird.
In my case, I have a scenario that when click certain part of an image it will trigger onclick events. I tried to detecte the position when the onTouch is fired, it works, but I think it's not a standard implementation, so what is the best practice for such case?
thanks.
here is codes like:
imgView.setOnTouchListener((OnTouchListener) new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
if(isIn(event.getX(), event.getY(), 124,3,221,36)){
ShowMemberInfo(R.string.app_m01);
} else if(isIn(event.getX(), event.getY(), 8,155,72,181)){
..
}
return true;
}
private boolean isIn(float x, float y, int fx, int fy, int tx, int ty) {
return x<tx && x > fx && y<ty && y>fy;
}
Try to use ImageButton
Simply implement onClickListener() for your ImageView.
Easiest way to implement onClick event is to include android:onClickMe="methodName" inside your <ImageView> in XML layout and define that method inside your activity file.
For example:
public void methodName(View v)
{
....
....
// do whatever you want for click even ton imageview
}
If you want to detect the position where user touched(Relative to the ImageView user touched), you can get the touch point from MotionEvent object.
Try to register a touch event listener for the ImageView and get the touched point position from MotionEvent object's getX() and getY() methods when touch event is triggered. And then define a rectangular area and using contains() to check whether the touch point is inside the area or not.
ImageView img = new ImageView(this);
img.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.w("Hit test", "is hit? "+isIn(event.getX(),event.getY(),0,0,120,120));
return false;
}
});
private boolean isIn(float x, float y, int fx, int fy, int tx, int ty){
return new Rect(fx,fy,tx,ty).contains((int)x,(int)y);
}
Hope this will be helpful to you. :)

Categories

Resources