Manikandan
Manikandan

Reputation: 1519

Need help while using the ScaleGestureDetector in android

I use the following code, to detect the ScaleGesture of the view. ScaleGestureDetector works fine. I have shown two images in my layout. While detecting the ScaleGesture, I reduce and increase the size of the images. I also need to click or touch on the image to do some process. If I use setOnClickListener instead of setOnTouchListener, the ScaleGestureDetector didn't work. While touching the screen with two fingers, the setOnTouchListener fires before ScaleGestureDetector. How can I achieve both ontouch and scaleGesture.

package com.pinch.detect;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class PinchDetectorActivity extends Activity {
    TextView textGestureAction;
    ImageView img1,img2;
    static Bitmap bm, bm1;
    String url1="url1111";
        String url2="url2222";

    private ScaleGestureDetector scaleGestureDetector;

      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
          textGestureAction = (TextView)findViewById(R.id.GestureAction);
          img1=(ImageView)findViewById(R.id.img_left);
          img2=(ImageView)findViewById(R.id.img_right);

        try {
            URL aURL = new URL(url1);
            // parseBitmap(aURL);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();

            /* Buffered is always good for a performance plus. */
            BufferedInputStream bis = new BufferedInputStream(is);

            /* Decode url-data to a bitmap. */
            bm = BitmapFactory.decodeStream(bis);

            bis.close();
            is.close();

            /* Apply the Bitmap to the ImageView that will be returned. */

            img1.setImageBitmap(bm);

            URL aURL1 = new URL(url2);
            URLConnection conn1 = aURL1.openConnection();
            conn1.connect();
            InputStream is1 = conn1.getInputStream();

            BufferedInputStream bis1 = new BufferedInputStream(is1);

            bm1 = BitmapFactory.decodeStream(bis1);

            bis1.close();
            is1.close();

            img2.setImageBitmap(bm1);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          scaleGestureDetector = new ScaleGestureDetector(this,
            new MySimpleOnScaleGestureListener());

          img1.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), "clicked image 1", Toast.LENGTH_SHORT).show();
                return false;
            }
        });

          img2.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    Toast.makeText(getApplicationContext(), "clicked image 2", Toast.LENGTH_SHORT).show();
                    return false;
                }
            });

         /* img1.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Toast.makeText(getApplicationContext(), "clicked image 1", Toast.LENGTH_SHORT).show();
                }
            });
          img2.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Toast.makeText(getApplicationContext(), "clicked image 2", Toast.LENGTH_SHORT).show();
                }
            });*/
      }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
     // TODO Auto-generated method stub
     scaleGestureDetector.onTouchEvent(event);
     return true;
    }

    public class MySimpleOnScaleGestureListener extends
    SimpleOnScaleGestureListener {

     @Override
     public boolean onScale(ScaleGestureDetector detector) {
      // TODO Auto-generated method stub

      float scaleFactor = detector.getScaleFactor();
      if(scaleFactor > 1){
          Log.v("inside scale factor if","if");
       textGestureAction.setText("Scale Out: " + String.valueOf(scaleFactor));

        Bitmap resizedbitmap = Bitmap.createScaledBitmap(bm, 200,
                480, true);
        img1.setImageBitmap(resizedbitmap);
        Bitmap resizedbitmap1 = Bitmap.createScaledBitmap(bm1, 200,
                480, true);
        img2.setImageBitmap(resizedbitmap1);

      }else{
          Log.v("inside scale factor else","else");
       textGestureAction.setText("Scale In: " + String.valueOf(scaleFactor));


        Bitmap resizedbitmap = Bitmap.createScaledBitmap(bm, 400,
                480, true);

        img1.setImageBitmap(resizedbitmap);

        Bitmap resizedbitmap1 = Bitmap.createScaledBitmap(bm1, 400,
                480, true);

        img2.setImageBitmap(resizedbitmap1);


      }

      return true;
     }
    }
    }

Upvotes: 1

Views: 2796

Answers (2)

mdupls
mdupls

Reputation: 2012

You are overriding onTouchEvent in your activity. In this method you are passing the events to your ScaleGestureDetector, but the problem is that only touch events that are not handled by the children views will be sent here. You are returning false in the children onTouch() methods. That is good... the onTouchEvent in your activity should be called next.

If you want to consume an event that should be sent to your children views you should take a look at onInterceptTouchEvent(MotionEvent event) in ViewGroup. http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent). Here, if you want to consume the event, return true. The following events will be sent to the ViewGroup's onTouchEvent method. If you return false, the events will be sent to the children of the ViewGroup.

You will have to extend a ViewGroup in order to override this method of course.

Let me know if this is the correct understanding of your question. I can try to help some more if possible.

Upvotes: 1

Oasis Feng
Oasis Feng

Reputation: 7510

The onTouchEvent() should be implemented like this:

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean handled = scaleGestureDetector.onTouchEvent(event);
    return super.onTouchEvent(event) || handled;
}

Upvotes: 1

Related Questions