Android Open Source - ImproveMyCity-Mobile Image View_ Zoom






From Project

Back to project page ImproveMyCity-Mobile.

License

The source code is released under:

GNU General Public License

If you think the Android project ImproveMyCity-Mobile listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

// ImageView_Zoom
package com.mk4droid.IMC_Core;
/*w  w  w  .ja  v a2  s. co  m*/
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;

import com.mk4droid.IMC_Activities.Fragment_Issue_Details;

/**
 * This is a custom ImageView that also incorporates zoom gestures.
 * 
 * @copyright   Copyright (C) 2012 - 2013 Information Technology Institute ITI-CERTH. All rights reserved.
 * @license     GNU Affero General Public License version 3 or later; see LICENSE.txt
 * @author      Dimitrios Ververidis for the Multimedia Group (http://mklab.iti.gr). 
 */
public class ImageView_Zoom extends ImageView {

  private static final int INVALID_POINTER_ID = -1;

  private float mPosX;
  private float mPosY;

  private float mLastTouchX;
  private float mLastTouchY;

  private float mLastGestureX;
  private float mLastGestureY;

  private int mActivePointerId = INVALID_POINTER_ID;

  private ScaleGestureDetector mScaleDetector;
  private float mScaleFactor = 1.f;

  //    PointF mid = new PointF();  

  boolean resetFlag = false;

  /* (non-Javadoc)
   * @see android.view.View#onConfigurationChanged(android.content.res.Configuration)
   */
  @Override
  protected void onConfigurationChanged(Configuration newConfig) {
    resetFlag = true;
    invalidate();
    super.onConfigurationChanged(newConfig);

  }

  /** Constructor with 2 arguments of this class */
  public ImageView_Zoom(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());

    getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        setImageBitmap(Fragment_Issue_Details.bmI); 
      }
    });
  }

  /** Constructor with 3 arguments of this class */
  public ImageView_Zoom(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
  }

  /** Main functionality */
  @Override
  public boolean onTouchEvent(MotionEvent ev) {

    mScaleDetector.onTouchEvent(ev);

    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
      if (!mScaleDetector.isInProgress()) {

        final float x = ev.getX();
        final float y = ev.getY();

        mLastTouchX = x;
        mLastTouchY = y;
        mActivePointerId = ev.getPointerId(0);
      }
      break;
    }
    case MotionEvent.ACTION_POINTER_1_DOWN: {
      if (mScaleDetector.isInProgress()) {
        final float gx = mScaleDetector.getFocusX();
        final float gy = mScaleDetector.getFocusY();
        mLastGestureX = gx;
        mLastGestureY = gy;
      }
      break;
    }
    case MotionEvent.ACTION_MOVE: {
      // Only move if the ScaleGestureDetector isn't processing a gesture.
      if (!mScaleDetector.isInProgress()) {
        final int pointerIndex = ev.findPointerIndex(mActivePointerId);
        final float x = ev.getX(pointerIndex);
        final float y = ev.getY(pointerIndex);

        final float dx = x - mLastTouchX;
        final float dy = y - mLastTouchY;

        mPosX += dx;
        mPosY += dy;

        invalidate();

        mLastTouchX = x;
        mLastTouchY = y;
      }
      else{
        final float gx = mScaleDetector.getFocusX();
        final float gy = mScaleDetector.getFocusY();

        final float gdx = gx - mLastGestureX;
        final float gdy = gy - mLastGestureY;

        mPosX += gdx;
        mPosY += gdy;

        invalidate();

        mLastGestureX = gx;
        mLastGestureY = gy;
      }
      break;
    }
    case MotionEvent.ACTION_UP: {
      mActivePointerId = INVALID_POINTER_ID;
      break;
    }
    case MotionEvent.ACTION_CANCEL: {
      mActivePointerId = INVALID_POINTER_ID;
      break;
    }
    case MotionEvent.ACTION_POINTER_UP: {
      final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
          >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
          final int pointerId = ev.getPointerId(pointerIndex);

          if (pointerId == mActivePointerId) {
            // This was our active pointer going up. Choose a new
            // active pointer and adjust accordingly.
            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            mLastTouchX = ev.getX(newPointerIndex);
            mLastTouchY = ev.getY(newPointerIndex);
            mActivePointerId = ev.getPointerId(newPointerIndex);
          }
          else{
            final int tempPointerIndex = ev.findPointerIndex(mActivePointerId);
            mLastTouchX = ev.getX(tempPointerIndex);
            mLastTouchY = ev.getY(tempPointerIndex);
          }

          break;
    }
    }

    return true;
  }

  /** Draw the scaled image */
  @Override
  public void onDraw(Canvas canvas) {

    if (resetFlag){
      canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

      mPosX = mPosY = mLastTouchX = mLastTouchY = mLastGestureX = mLastGestureY = 0;
      mScaleFactor = 1;

      setScaleType(ScaleType.FIT_CENTER);
      setImageBitmap(Fragment_Issue_Details.bmI);

      resetFlag = false;
      canvas.restore();
    } else {

      if (mScaleDetector.isInProgress()) {
        canvas.scale(mScaleFactor, mScaleFactor, mScaleDetector.getFocusX(), mScaleDetector.getFocusY());
      } else{
        canvas.translate(mPosX/2, mPosY/2);
        canvas.scale(mScaleFactor, mScaleFactor, mLastGestureX, mLastGestureY);
      }

    }

    super.onDraw(canvas);
  }

  
  private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
      mScaleFactor *= detector.getScaleFactor();
      mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));       // Don't let the object get too small or too large.
      invalidate();
      return true;
    }
  }
}




Java Source Code List

com.mk4droid.IMC_Activities.Activity_Information_Detailed.java
com.mk4droid.IMC_Activities.Activity_Register.java
com.mk4droid.IMC_Activities.Activity_Setup.java
com.mk4droid.IMC_Activities.Activity_Splash_Login.java
com.mk4droid.IMC_Activities.Activity_Thinking.java
com.mk4droid.IMC_Activities.FActivity_TabHost.java
com.mk4droid.IMC_Activities.Fragment_Comments.java
com.mk4droid.IMC_Activities.Fragment_Filters.java
com.mk4droid.IMC_Activities.Fragment_Issue_Details.java
com.mk4droid.IMC_Activities.Fragment_List.java
com.mk4droid.IMC_Activities.Fragment_Map.java
com.mk4droid.IMC_Activities.Fragment_NewIssueA.java
com.mk4droid.IMC_Activities.Fragment_NewIssueB.java
com.mk4droid.IMC_Activities.package-info.java
com.mk4droid.IMC_Constructors.Category.java
com.mk4droid.IMC_Constructors.Comment.java
com.mk4droid.IMC_Constructors.IssueListItem.java
com.mk4droid.IMC_Constructors.IssuePic.java
com.mk4droid.IMC_Constructors.Issue.java
com.mk4droid.IMC_Constructors.VersionDB.java
com.mk4droid.IMC_Constructors.Vote.java
com.mk4droid.IMC_Constructors.package-info.java
com.mk4droid.IMC_Core.FilterCateg_ExpandableListAdapter.java
com.mk4droid.IMC_Core.ImageView_Zoom.java
com.mk4droid.IMC_Core.InfoWindowAdapterButtoned.java
com.mk4droid.IMC_Core.Issues_ListAdapter.java
com.mk4droid.IMC_Core.Preference_About.java
com.mk4droid.IMC_Core.Preference_AccountOperations.java
com.mk4droid.IMC_Core.Preference_Email.java
com.mk4droid.IMC_Core.Preference_PlainText.java
com.mk4droid.IMC_Core.Preference_Reset.java
com.mk4droid.IMC_Core.Preference_SeekBar.java
com.mk4droid.IMC_Core.SpinnerAdapter_NewIssueCateg.java
com.mk4droid.IMC_Core.package-info.java
com.mk4droid.IMC_Services.DatabaseHandler.java
com.mk4droid.IMC_Services.Download_Data.java
com.mk4droid.IMC_Services.InternetConnCheck.java
com.mk4droid.IMC_Services.Security.java
com.mk4droid.IMC_Services.Service_Data.java
com.mk4droid.IMC_Services.Service_Location.java
com.mk4droid.IMC_Services.Upload_Data.java
com.mk4droid.IMC_Services.package-info.java
com.mk4droid.IMC_Store.Constants_API.java
com.mk4droid.IMC_Store.Phptasks.java
com.mk4droid.IMC_Store.package-info.java
com.mk4droid.IMC_Utils.GEO.java
com.mk4droid.IMC_Utils.My_Crypt_Utils.java
com.mk4droid.IMC_Utils.My_Date_Utils.java
com.mk4droid.IMC_Utils.My_System_Utils.java
com.mk4droid.IMC_Utils.RestCaller.java
com.mk4droid.IMC_Utils.RestClient.java
com.mk4droid.IMC_Utils.package-info.java