捏缩放和拖动图像视图会远离屏幕?

时间:2013-01-04 07:44:29

标签: android imageview drag pinchzoom

我需要拖动和捏缩放图像视图。我上网并从here获得了代码。它效果很好,但是当我放大更多时,它会超出屏幕。我想在屏幕上保持缩放和拖动。我尝试了以下方法,但它对我不起作用。

我将imageview的Tanslate属性设置为:
matrix.setTranslate(width / 2, height / 2);
其中宽度和高度是屏幕宽度和高度。

我试图检查这种情况,但它从未帮助过我:

case MotionEvent.ACTION_MOVE:

  if (mode == DRAG) {

     int newX = event.getX() - start.x;
     int newY = event.getY() - start.y;
     if ( (newX <= 0 || newX >= screenWidth) ||
          (newY <= 0 || newY >= screenHeight) )
         break;

     matrix.set(savedMatrix);
     matrix.postTranslate(newX, newY);

完整源代码:

public class Touch extends Activity {

// 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;

// Widgets

private Gallery galleryIcons;
private Intent intent;
private ImageLoader imageloader = null;
private String filePath = null;
private Uri myUri = null;
private Bitmap preview_bitmap = null;
private Utils utils = null;
private ImageView imgRawBg;
private View adminIcons = null;
private View icon_cost_description = null;
public ProgressDialog mProgressDialog;
public ProgressDialog mProgDiagSndToServer;
private String uploadStatus = null;

private Activity activity;
private InputStream is;
private ImageView imgIcon;
private TextView txtImgMetaTitle;
private TextView txtImgTitle;
private TextView txtImgDesc;
private TextView btnImgPrice;
private TextView btnImgCancel;
private Dialog inAppDialog;
private TextView txtTitle;
private Button btnBuyIcon;
private Button btnCancelDialog;
protected int mIconIndex = 0;
private View yesOrNoConfirmation;
private ImageButton btnOkConfirm;
private ImageButton btnCancel;
private ImageView imgToDragAndPan;
private FrameLayout saveImage;
private File imageFile;
private File photo;
private boolean serverUploadException = false;
private String uploadPhotoID = null;

static int height;
static int width;

private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 5.0f;

// Menus and its properties

private static final int CHANGE_TOUCH_MODE_MENU_ID = Menu.FIRST;
private static final int SAVE_PROCESSED_IMAGE = 3;
public static final boolean Debugging = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.dragview);

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    height = metrics.heightPixels;
    width = metrics.widthPixels;

    setupViews();

    imgToDragAndPan.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent rawEvent) {
            WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
            ImageView view = (ImageView) v;

            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) {

                 int newX = event.getX() - start.x;
     int newY = event.getY() - start.y;
     if ( (newX <= 0 || newX >= screenWidth) ||
      (newY <= 0 || newY >= screenHeight) )
     break;


                    matrix.set(savedMatrix);
                    matrix.postTranslate(newX, newY);

                    // 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;
        }
    });

    matrix.setTranslate(width / 2, height / 2);
    // matrix.setTranslate(1f, 1f);

    imgToDragAndPan.setImageMatrix(matrix);

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 4;
    preview_bitmap = BitmapFactory.decodeStream(is, null, options);

    galleryIcons = (Gallery) findViewById(R.id.galleryIcons);
    galleryIcons.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> arg0, View arg1, int index,
                long arg3) {
            mIconIndex = index;
            if (SplashScreen.adminIcons.get(index).getPaymentType()
                    .equals("0")) {

                imageloader.DisplayImage(SplashScreen.adminIcons.get(index)
                        .getLargeIcons(), imgToDragAndPan);
                imgToDragAndPan.setVisibility(View.VISIBLE);
                adminIcons.setVisibility(View.VISIBLE);
                icon_cost_description.setVisibility(View.GONE);

            } else {
                imgToDragAndPan.setVisibility(View.GONE);
                adminIcons.setVisibility(View.GONE);
                icon_cost_description.setVisibility(View.VISIBLE);
                imageloader.DisplayImage(SplashScreen.adminIcons.get(index)
                        .getSmallIcons(), imgIcon);
                txtImgMetaTitle.setText(SplashScreen.adminIcons.get(index)
                        .getName());
                txtImgTitle.setText(SplashScreen.adminIcons.get(index)
                        .getName());
                txtImgDesc.setText(SplashScreen.adminIcons.get(index)
                        .getDescription());
                btnImgPrice.setText(SplashScreen.adminIcons.get(index)
                        .getPrice());
                btnImgCancel.setText(Constant.cancel);
            }
        }
    });

    btnImgCancel.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            adminIcons.setVisibility(View.VISIBLE);
            icon_cost_description.setVisibility(View.GONE);
        }
    });

    btnImgPrice.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            ShowBuyDialog();
        }
    });

    btnOkConfirm.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            if (utils.isConnectingToInternet(Touch.this)) {
                new UploadImagesToServer().execute();
            } else {
                utils.showToast(getApplicationContext(),
                        Constant.noNetworkConnection);
            }
        }
    });

    btnCancel.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            imgToDragAndPan.setEnabled(true);
            adminIcons.setVisibility(View.VISIBLE);
            icon_cost_description.setVisibility(View.GONE);
            yesOrNoConfirmation.setVisibility(View.GONE);
        }
    });

    activity.runOnUiThread(new Runnable() {
        public void run() {
            mProgressDialog = ProgressDialog.show(Touch.this,
                    "Please wait...", "Loading..");

            File photo = new File(myUri.getPath());
            preview_bitmap = utils.decodeFile(photo);
            imgRawBg.setImageBitmap(preview_bitmap);
            galleryIcons.setAdapter(new AdminIconsAdapter(Touch.this,
                    SplashScreen.adminIcons));

            if (mProgressDialog.isShowing() && mProgressDialog != null) {
                mProgressDialog.dismiss();
            }
        }
    });
}

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    menu.add(0, CHANGE_TOUCH_MODE_MENU_ID, 0, "Show / Hide");
    menu.add(0, SAVE_PROCESSED_IMAGE, 0, "Save Image");
    return true;
}

public boolean onPrepareOptionsMenu(Menu menu) {

    if (yesOrNoConfirmation.isShown()) {
        menu.findItem(SAVE_PROCESSED_IMAGE).setVisible(false);
        menu.findItem(CHANGE_TOUCH_MODE_MENU_ID).setVisible(false);
    } else {
        menu.findItem(SAVE_PROCESSED_IMAGE).setVisible(true);
        menu.findItem(CHANGE_TOUCH_MODE_MENU_ID).setVisible(true);
    }
    return super.onPrepareOptionsMenu(menu);
}

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case CHANGE_TOUCH_MODE_MENU_ID: {

        if (adminIcons.isShown()) {
            adminIcons.setVisibility(View.GONE);
        } else {
            adminIcons.setVisibility(View.VISIBLE);
        }
        return true;
    }
    case SAVE_PROCESSED_IMAGE: {
        imgToDragAndPan.setEnabled(false);
        adminIcons.setVisibility(View.GONE);
        icon_cost_description.setVisibility(View.GONE);
        saveProcessedImage();
        processedImgHandler.sendEmptyMessageDelayed(0, 500);
    }
    }
    return super.onOptionsItemSelected(item);
}

Handler processedImgHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        preview_bitmap = utils.decodeFile(imageFile);
        yesOrNoConfirmation.setVisibility(View.VISIBLE);
        super.handleMessage(msg);
    }
};

private void saveProcessedImage() {

    photo = new File(Environment.getExternalStorageDirectory()
            + "/Mashallah", "photoToShare.png");

    // create bitmap screen capture
    Bitmap bitmap = null;
    View v1 = saveImage.getRootView();
    v1.setDrawingCacheEnabled(true);
    bitmap = Bitmap.createBitmap(v1.getDrawingCache());
    v1.setDrawingCacheEnabled(false);
    OutputStream outStream = null;
    imageFile = new File(photo.getAbsolutePath());

    try {
        outStream = new FileOutputStream(photo.getAbsolutePath());
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
        outStream.flush();
        outStream.close();

    } catch (FileNotFoundException e) {

    } catch (IOException e) {

    }
}

private void setupViews() {
    utils = new Utils();
    intent = getIntent();
    imageloader = new ImageLoader(Touch.this);
    activity = this;
    filePath = intent.getStringExtra("filePath");
    myUri = Uri.parse(filePath);
    imgToDragAndPan = (ImageView) findViewById(R.id.imgToDrag);
    imgRawBg = (ImageView) findViewById(R.id.imgbg);

    // imgToDragAndPan.getLayoutParams().height = height;
    // imgToDragAndPan.getLayoutParams().width = width;
    // imgToDragAndPan.setMaxHeight(height);
    // imgToDragAndPan.setMaxWidth(width);
    //
    // imgRawBg.getLayoutParams().height = height;
    // imgRawBg.getLayoutParams().width = width;
    // imgRawBg.setMaxHeight(height);
    // imgRawBg.setMaxWidth(width);

    icon_cost_description = (View) findViewById(R.id.icon_cost_description);
    adminIcons = (View) findViewById(R.id.adminIcons);
    yesOrNoConfirmation = (View) findViewById(R.id.confirm_yes_or_no);
    saveImage = (FrameLayout) findViewById(R.id.saveImage);

    // Icon_cost_description

    imgIcon = (ImageView) findViewById(R.id.imgIcon);
    txtImgMetaTitle = (TextView) findViewById(R.id.txtImgMetaTitle);
    txtImgTitle = (TextView) findViewById(R.id.txtImgTitle);
    txtImgDesc = (TextView) findViewById(R.id.txtImgDesc);
    btnImgPrice = (TextView) findViewById(R.id.btnImgPrice);
    btnImgCancel = (TextView) findViewById(R.id.btnImgCancel);

    // Confirm_yes_no layout

    btnOkConfirm = (ImageButton) findViewById(R.id.btnOkConfirm);
    btnCancel = (ImageButton) findViewById(R.id.btnCancel);

    // Setting visibility

    imgToDragAndPan.setVisibility(View.INVISIBLE);
    yesOrNoConfirmation.setVisibility(View.GONE);
    icon_cost_description.setVisibility(View.GONE);

}




/** Determine the space between the first two fingers */
private float spacing(WrapMotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);
}

/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, WrapMotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
}

}

2 个答案:

答案 0 :(得分:1)

试试这个,

我有一个解决方案,我希望它对你有用,

try to use TouchImageView instead of ImageView in Layout.because touchimageview have property that zooming in or out itself

https://github.com/MikeOrtiz/TouchImageView from this link you learn how to use touchimageview...

<com.luminous.pick.TouchImageView
                android:id="@+id/img2"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

Then After implement onDragListener of imageview so you can get DRAG And Drop of Imageview easily...

@Override
public boolean onDrag(View v, DragEvent event) {

    switch (event.getAction()) {

        case DragEvent.ACTION_DROP:

            ImageView target = (ImageView) v;
            ImageView dragged = (ImageView) event.getLocalState();

            Drawable target_draw = target.getDrawable();
            Drawable dragged_draw = dragged.getDrawable();

            dragged.setImageDrawable(target_draw);
            target.setImageDrawable(dragged_draw);

   }
    return true;
}

我希望你能尽快解决问题....

答案 1 :(得分:0)

尝试使用event.getRawX()getRawY();

并且比较语句会检查 drag 是否超过屏幕宽度高度。它应该是像

这样的东西
 int newX = event.getRawX();//or +/- the current width of the element under drag
 int newY = event.getRawY();
 if ( (newX <= 0 || newX >= screenWidth) ||
      (newY <= 0 || newY >= screenHeight) )
     break;

请检查是否有帮助。