English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

DragImageView Implementation for Pull-down Dragging Image Scaling Effect in Android

DragImageView pulls down and drags the image to zoom in, first show the image:

The main class: inherits from RelativeLayout, and adds ImageView inside RelativeLayout, changing the scale of ImageView through touch events. When calculating the scale, it ensures that when the finger moves to the bottom of the screen, the bottom of the image also reaches the bottom of the screen. When the finger is released, the image gradually bounces back.

package com.example.dragimagescale; 
import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.os.Handler; 
import android.os.Message; 
import android.util.AttributeSet; 
import android.util.DisplayMetrics; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.WindowManager; 
import android.widget.ImageView; 
import android.widget.ImageView.ScaleType; 
import android.widget.RelativeLayout; 
public class DragScaleImageView extends RelativeLayout { 
 private String TAG = "DragScaleImageView"; 
 private static final int BACK_SCALE = 1010; 
 private Context mContext; 
 private AttributeSet attrs; 
 private int displayWidth = 0; 
 private int displayHeight = 0; 
 private int mImageId; 
 private Bitmap bmp; 
 private ImageView imageView; 
 /** Whether in the rebound state */ 
 private boolean isBacking = false; 
 /** Used to record the coordinate position of the image being dragged */ 
 private Matrix matrix = new Matrix(); 
 /** Used to record the coordinate position when the image is to be dragged */ 
 private Matrix currentMatrix = new Matrix(); 
 private Matrix defaultMatrix = new Matrix(); 
 /** Image width and height */ 
 private float imgHeight, imgWidth; 
 /** Initial state */ 
 private int mode = 0; 
 /** Drag photo mode */ 
 private final int MODE_DRAG = 1; 
 private float scaleY = 0; 
 /** Used to record the coordinate position at the beginning */ 
 private PointF startPoint = new PointF(); 
 /** Used to record the Y coordinate position in the entire screen at the beginning */ 
 private float startRawY = 0; 
 float scale = 1; 
 private TouchEventListener touchEventListener = null; 
 private BackScaleListener backScaleListener = null; 
 public DragScaleImageView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
  // TODO Auto-generated constructor stub 
  this.mContext = context; 
  this.attrs = attrs; 
  initView(); 
 } 
 public DragScaleImageView(Context context) { 
  super(context); 
  // TODO Auto-generated constructor stub 
  this.mContext = context; 
  initView(); 
 } 
 public DragScaleImageView(Activity activity, Bitmap resBitmap, int width, 
   int height) { 
  super(activity); 
 } 
 /** 
  * Initialize image 
  */ 
 private void initView() { 
  /* Obtain screen resolution size */ 
  DisplayMetrics dm = new DisplayMetrics(); 
  WindowManager mWm = (WindowManager) mContext 
    .getSystemService(Context.WINDOW_SERVICE); 
  mWm.getDefaultDisplay().getMetrics(dm); 
  displayWidth = dm.widthPixels; 
  displayHeight = dm.heightPixels; 
  TypedArray a = mContext.obtainStyledAttributes(attrs, 
    R.styleable.DragScaleImageView); 
  mImageId = a.getResourceId(R.styleable.DragScaleImageView_scale_image, 
    0); 
  a.recycle(); 
  if (null == bmp && mImageId != 0) { 
   bmp = BitmapFactory.decodeResource(getResources(), mImageId); 
   float scale = (float) displayWidth / (float) bmp.getWidth();// 1080/1800 
   matrix.postScale(scale, scale, 0, 0); 
   imgHeight = scale; * bmp.getHeight(); 
   imgWidth = scale; * bmp.getWidth(); 
  } else { 
   imgHeight = displayWidth; 
   imgWidth = displayWidth; 
  } 
  initImageView(); 
 } 
 private void initImageView() { 
  imageView = new ImageView(mContext); 
  imageView.setImageMatrix(matrix); 
  defaultMatrix.set(matrix); 
  Log.w(TAG, "imgWidth :" + imgWidth); 
  Log.w(TAG, "imgHeight :" + imgHeight); 
  RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( 
    (int) imgWidth, (int) imgHeight); 
  imageView.setLayoutParams(layoutParams); 
  imageView.setImageBitmap(bmp); 
  imageView.setScaleType(ScaleType.CENTER_CROP); 
  this.addView(imageView); 
 } 
 /** 
  * Set the width and height of ImageView 
  * 
  * @param width 
  * @param height 
  */ 
 public void setImageWidthAndHeight(int width, int height) { 
  imgWidth = width; 
  imgHeight = height; 
  RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( 
    (int) imgWidth, (int) imgHeight); 
  imageView.setLayoutParams(layoutParams); 
 } 
 public boolean onTouchEvent(MotionEvent event) { 
  Log.w(TAG, "onTouchEvent :" + event.getAction()); 
  // When this View is placed inside a ScrollView, it may conflict with the parent control's touch event, so the parent control is not available when touching the control area 
  if (event.getAction() == MotionEvent.ACTION_UP) { 
   getParent().requestDisallowInterceptTouchEvent(false); 
  } else { 
   getParent().requestDisallowInterceptTouchEvent(true);// true indicates that the parent class is not available; 
  } 
  switch (event.getAction() & MotionEvent.ACTION_MASK) { 
  // Finger presses the screen 
  case MotionEvent.ACTION_DOWN: 
   if (isBacking) { 
    return super.onTouchEvent(event); 
   } 
   int[] location = new int[2]; 
   imageView.getLocationInWindow(location); 
   if (location[1] >= 0) { 
    mode = MODE_DRAG; 
    // Record the current moving position of ImageView 
    currentMatrix.set(imageView.getImageMatrix()); 
    startPoint.set(event.getX(), event.getY()); 
    startRawY = event.getRawY(); 
    Log.w(TAG, "onTouchEvent startRawY:" + startRawY); 
   } 
   break; 
  // The finger moves on the screen, and this event will be triggered continuously 
  case MotionEvent.ACTION_MOVE: 
   // Drag the image 
   if (mode == MODE_DRAG) { 
//    float dx = event.getX() - startPoint.x; // Get the distance of movement along the x-axis 
    float dy = event.getY() - startPoint.y; // Get the distance of movement along the y-axis 
    // Move at the position before moving without any movement 
    if (dy > 0) { 
     matrix.set(currentMatrix); 
     Log.w(TAG, "onTouchEvent dy:" + dy); 
     scale = ((dy / (displayHeight - startRawY) * (displayHeight - imgHeight)) + imgHeight) 
       / imgHeight; // Get scaling factor, when the finger moves to the bottom of the screen, the image also reaches the bottom of the screen 
     Log.w(TAG, "onTouchEvent scale:" + scale); 
     scaleY = dy; 
     RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams( 
       (int) (scale * imgWidth), (int) (scale * imgHeight)); 
     imageView.setLayoutParams(relativeLayout); 
     matrix.postScale(scale, scale, imgWidth / 2, 0); 
     imageView.setImageMatrix(matrix); 
    } 
   } 
   break; 
  // The finger leaves the screen 
  case MotionEvent.ACTION_UP: 
   // When the touch point leaves the screen, the image is restored 
   mHandler.sendEmptyMessage(BACK_SCALE); 
  case MotionEvent.ACTION_POINTER_UP: 
   // Cancel the image movement when two fingers move 
   mode = 0; 
   break; 
  } 
  // Set the Touch event listener 
  if (touchEventListener != null) { 
   touchEventListener.onTouchEvent(event); 
  } 
  return true; 
 } 
 /** gradually rebound */ 
 @SuppressLint("HandlerLeak") 
 private Handler mHandler = new Handler() { 
  @Override 
  public void handleMessage(Message msg) { 
   // TODO Auto-generated method stub 
   switch (msg.what) { 
   case BACK_SCALE: 
    scale = (scaleY / 2 + imgHeight) / (imgHeight);// Get scaling factor 
    if (scaleY > 0) { 
     isBacking = true; 
     matrix.set(currentMatrix); 
     RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams( 
       (int) (scale * imgWidth), (int) (scale * imgHeight)); 
     imageView.setLayoutParams(relativeLayout); 
     matrix.postScale(scale, scale, imgWidth / 2, 0); 
     imageView.setImageMatrix(matrix); 
     scaleY = (float) (scaleY / 2 - 1); 
     mHandler.sendEmptyMessageDelayed(BACK_SCALE, 20);// gradually rebound 
    } else { 
     scaleY = 0; 
     RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams( 
       (int) imgWidth, (int) imgHeight); 
     imageView.setLayoutParams(relativeLayout); 
     matrix.set(defaultMatrix); 
     imageView.setImageMatrix(matrix); 
     isBacking = false; 
    } 
    if (backScaleListener != null) { 
     backScaleListener.onBackScale(); 
    } 
    break; 
   default: 
    break; 
   } 
   super.handleMessage(msg); 
  } 
 }; 
 public void setTouchEventListener(TouchEventListener touchEventListener) { 
  this.touchEventListener = touchEventListener; 
 } 
 public void setBackScaleListener(BackScaleListener backScaleListener) { 
  this.backScaleListener = backScaleListener; 
 } 
 /** touch event listener */ 
 public interface TouchEventListener { 
  public void onTouchEvent(MotionEvent event); 
 } 
 /** bounce event listener */ 
 public interface BackScaleListener { 
  public void onBackScale(); 
 } 
} 

Called Activity:

package com.example.dragimagescale; 
import com.example.dragimagescale.DragScaleImageView.BackScaleListener; 
import com.example.dragimagescale.DragScaleImageView.TouchEventListener; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.MotionEvent; 
public class MainActivity extends Activity { 
 DragScaleImageView mDragScaleImageView; 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
  mDragScaleImageView = (DragScaleImageView) findViewById(R.id.dragScaleImageView); 
  /** Customize the width and height of ImageView, if not set, it will be compressed to the screen width according to the image width and height */ 
//  mDragScaleImageView.setImageWidthAndHeight(720, 300); 
  // touch event listener 
  mDragScaleImageView.setTouchEventListener(new TouchEventListener() { 
   @Override 
   public void onTouchEvent(MotionEvent event) { 
    // TODO Auto-generated method stub 
    // do something here 
   } 
  ); 
  // bounce event listener 
  mDragScaleImageView.setBackScaleListener(new BackScaleListener() { 
   @Override 
   public void onBackScale() { 
    // TODO Auto-generated method stub 
    // do something here 
   } 
  ); 
 } 
} 

XML Layout File:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android 
 xmlns:tools="http://schemas.android.com/tools 
 xmlns:dragscaleimageview="http://schemas.android.com/apk/res/com.example.dragimagescale" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:background="#ffffff" > 
 <com.example.dragimagescale.DragScaleImageView 
  android:id="@"+id/dragScaleImageView" 
  android:layout_width="match_parent"   
  android:layout_height="wrap_content" 
  dragscaleimageview:scale_image="@drawable/image" 
  > 
 </com.example.dragimagescale.DragScaleImageView> 
</RelativeLayout> 

Download:Source Code

That's all for this article. Hope it will be helpful to your learning, and also hope everyone will support the Yell Tutorial.

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, does not edit the content manually, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to notice#w.3Please report by email to codebox.com (replace # with @ when sending email) and provide relevant evidence. Once verified, this site will immediately delete the infringing content.

You May Also Like