Is there a common way to show a big image and enable the user to zoom in and out and pan the image?
Until now I found two ways:
@Robert Foss, @Mike Ortiz, thank you very much for your work. I merged your work, and completed Robert classes for android > 2.0 with Mike additional work.
As result of my work I present Android Touch Gallery, based on ViewPager and used modificated TouchImageView. Images loading by URL and you can zoom and drag them. You can find it here https://github.com/Dreddik/AndroidTouchGallery
Try using ZoomView
for zooming any other view.
http://code.google.com/p/android-zoom-view/ it's easy, free and fun to use!
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageDetail = (ImageView) findViewById(R.id.imageView1);
imageDetail.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
System.out.println("matrix=" + savedMatrix.toString());
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
startPoint.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(midPoint, 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() - startPoint.x, event.getY() - startPoint.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, midPoint.x, midPoint.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
@SuppressLint("FloatMath")
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);
}
});
}
and drawable folder should have bticn image file. perfectly works :)
Something like below will do it.
@Override public boolean onTouch(View v,MotionEvent e)
{
tap=tap2=drag=pinch=none;
int mask=e.getActionMasked();
posx=e.getX();posy=e.getY();
float midx= img.getWidth()/2f;
float midy=img.getHeight()/2f;
int fingers=e.getPointerCount();
switch(mask)
{
case MotionEvent.ACTION_POINTER_UP:
tap2=1;break;
case MotionEvent.ACTION_UP:
tap=1;break;
case MotionEvent.ACTION_MOVE:
drag=1;
}
if(fingers==2){nowsp=Math.abs(e.getX(0)-e.getX(1));}
if((fingers==2)&&(drag==0)){ tap2=1;tap=0;drag=0;}
if((fingers==2)&&(drag==1)){ tap2=0;tap=0;drag=0;pinch=1;}
if(pinch==1)
{
if(nowsp>oldsp)scale+=0.1;
if(nowsp<oldsp)scale-=0.1;
tap2=tap=drag=0;
}
if(tap2==1)
{
scale-=0.1;
tap=0;drag=0;
}
if(tap==1)
{
tap2=0;drag=0;
scale+=0.1;
}
if(drag==1)
{
movx=posx-oldx;
movy=posy-oldy;
x+=movx;
y+=movy;
tap=0;tap2=0;
}
m.setTranslate(x,y);
m.postScale(scale,scale,midx,midy);
img.setImageMatrix(m);img.invalidate();
tap=tap2=drag=none;
oldx=posx;oldy=posy;
oldsp=nowsp;
return true;
}
public void onCreate(Bundle b)
{
super.onCreate(b);
img=new ImageView(this);
img.setScaleType(ImageView.ScaleType.MATRIX);
img.setOnTouchListener(this);
path=Environment.getExternalStorageDirectory().getPath();
path=path+"/DCIM"+"/behala.jpg";
byte[] bytes;
bytes=null;
try{
FileInputStream fis;
fis=new FileInputStream(path);
BufferedInputStream bis;
bis=new BufferedInputStream(fis);
bytes=new byte[bis.available()];
bis.read(bytes);
if(bis!=null)bis.close();
if(fis!=null)fis.close();
}
catch(Exception e)
{
ret="Nothing";
}
Bitmap bmp=BitmapFactory.decodeByteArray(bytes,0,bytes.length);
img.setImageBitmap(bmp);
setContentView(img);
}
For viewing complete program see here: Program to zoom image in android
I used a WebView and loaded the image from the memory via
webview.loadUrl("file://...")
The WebView handles all the panning zooming and scrolling. If you use wrap_content the webview won't be bigger then the image and no white areas are shown. The WebView is the better ImageView ;)
You can try using the LayoutParams for this
public void zoom(boolean flag){
if(flag){
int width=40;
int height=40;
}
else{
int width=20;
int height=20;
}
RelativeLayout.LayoutParams param=new RelativeLayout.LayoutParams(width,height); //use the parent layout of the ImageView;
imageView.setLayoutParams(param); //imageView is the view which needs zooming.
}
ZoomIn = zoom(true); ZoomOut = zoom(false);