Zoom in and drag in custom view with bitmap in Android

Source: Internet
Author: User
Tags gety

A basic realization idea:

Implements a custom View–myimageview class based on the view class. In the activity class that uses view, the Ontouchlistener interface is completed to monitor and process the Motionevent event, and the common motionevent events are as follows:

Action_down event, recording translation start point
Action_up event, ending translation event handling
Action_move event, record translation point, calculate distance from start point, realize bitmap translation, calculate distance between two points when multi-touch, achieve image amplification
Action_pointer_down event, calculates the distance between two points, as the initial distance, to achieve the image gesture magnification when used.
Action_pointer_up event, ending two-point touch magnification image processing


Zoom in and drag
The bitmap object is dragged on the view based on a single touch, and the edge of the view is detected to prevent dragging across the bounds. The bitmap object is magnified on the view based on two touch points, and the magnification is detected. Based on the Matrix object implementation of the bitmap on the View zoom and translation transformation, and matrix object is the implementation of the image geometric transformation in Android matrices, support translation, amplification, reduction, error cutting, rotation and other common operations.

Update and display of bitmap objects in view
By overloading the OnDraw method, the canvas implementation is used to draw the bitmap object, and the refresh of the view is implemented through the View.invalidate () method.

The important methods of the Myimageview class are explained:
Initparameters () Initializes all parameters that need to be used
Setstartpoint () sets the starting point coordinates of the image translation

Setmovepoint () sets the moving point coordinates of the image translation, then sets the starting point position, calculates the distance between them, and obtains the two parameter values SX, SY, which the bitmap object needs to translate. It also includes a check code that ensures that the image does not cross the view boundary.

Savepreviousresult () Saves the current panning data, and the next time you can continue to pan the bitmap object on the secondary basis.

ZoomIn () based on Euclidean distance between two points, the magnification is obtained by the initial distance comparison, and the magnification of the bitmap on the View object is realized.


The Matrix's API for zooming in and panning

The Matrix.postscale method and the Matrix.posttranslate method can translate and enlarge without changing the bitmap object itself.


Two: Code implementation

The custom view class uses the following XML layout:

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:tools= "http// Schemas.android.com/tools "    android:layout_width=" match_parent "    android:layout_height=" Match_parent "    android:paddingbottom= "@dimen/activity_vertical_margin"    android:paddingleft= "@dimen/activity_ Horizontal_margin "    android:paddingright=" @dimen/activity_horizontal_margin "    android:paddingtop=" @dimen /activity_vertical_margin "    tools:context=". Mainactivity ">    <com.example.matrixdemo.myimageview        android:id=" @+id/myview "        android:layout_ Width= "Fill_parent"        android:layout_height= "fill_parent"        android:text= "@string/hello_world"/></ Relativelayout>
The custom View implementation code is as follows:

Package Com.example.matrixdemo;import Android.content.context;import Android.graphics.bitmap;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.matrix;import Android.graphics.paint;import Android.graphics.paint.style;import Android.graphics.point;import Android.graphics.rect;import Android.util.attributeset;import Android.view.view;public class MyImageView extends  View {private Paint mpaint;private Bitmap bitmap;private Matrix matrix;//Pan start point and move point private dot startpoint;private points Movepoint;private float initdistance;//record current translation distance private int sx;private int sy;//Bao Cunping move State private int oldsx;private int olds y;//scale rateprivate float widthrate;private float heightrate;public myimageview (context context) {super (context);} Public Myimageview (context context, AttributeSet Attrs) {Super (context, attrs);} public void SetBitmap (Bitmap Bitmap) {this.bitmap = Bitmap;} private void Initparameters () {//initialization brush mpaint = new Paint (); Mpaint.setcolor (color.black); matrix = nEW Matrix (); if (bitmap! = null) {Float IW = bitmap.getwidth (); Float ih = bitmap.getheight (); Float width = This.getwidth (); FL Oat height = this.getheight ();//initial scaling ratio widthrate = Width/iw;heightrate = Height/ih;} SX = 0;sy = 0;OLDSX = 0;oldsy = 0;} public void Setstartpoint (point startPoint) {this.startpoint = StartPoint;} public void Setinitdistance (float initdistance) {this.initdistance = initdistance;} public void ZoomIn (float distance) {float rate = distance/this.initdistance;float IW = Bitmap.getwidth (); Float ih = Bitma P.getheight (); Float width = this.getwidth (); Float height = this.getheight ();//Get scale ratewidthrate = (WIDTH/IW) * r Ate;heightrate = (height/ih) * rate;//make it same as view sizefloat IWR = (WIDTH/IW); float ihr = (height/ih); if (i WR >= widthrate) {widthrate = (WIDTH/IW);} if (Ihr >= heightrate) {heightrate = (height/ih);} Go to CENTEROLDSX = (int) ((width-widthrate * IW)/2), oldsy = (int) ((height-heightrate * ih)/2);} public void Setmovepoint (Point movepoint) {this.movepoint = MOVEPOINT;SX = This.movepoint.x-this.startpoint.x;sy = THIS.MOVEPOINT.Y-THIS.STARTP Oint.y;float IW = Bitmap.getwidth (); Float ih = Bitmap.getheight ();//detect edge int deltax = (int) ((widthrate * iw)-This.getwid th ()); int deltay = (int) ((heightrate * ih)-this.getheight ()); if (SX + THIS.OLDSX) >= 0) {this.oldsx = 0;SX = 0;} else if (SX + this.oldsx) <=-deltax) {this.oldsx =-DELTAX;SX = 0;} if (sy + this.oldsy) >= 0) {this.oldsy = 0;this.sy = 0;} else if (sy + this.oldsy) <=-deltay) {this.oldsy =-deltay;this.sy = 0;} Float width = this.getwidth ();//initial scaling ratio float IWR = width/iw;if (IWR = = widthrate) {SX = 0;sy = 0;OLDSX = 0;oldsy = 0;}} public void Savepreviousresult () {this.oldsx = this.sx + this.oldsx;this.oldsy = this.sy + this.oldsy;//zerosx = 0;sy = 0; } @Overrideprotected void OnDraw (canvas canvas) {if (Matrix = = null) {initparameters ();} if (bitmap! = null) {Matrix.reset (); Matrix.postscale (Widthrate, heightrate); Matrix.posttranslate (OLDSX+SX, Oldsy+ sy); Canvas.drawbitmap (bitmap, Matrix, mpaint);} else{//fill Rectrect rect = new Rect (0, 0, getwidth (), getheight ()); Mpaint.setantialias (true); Mpaint.setcolor ( Color.Black); Mpaint.setstyle (Style.fill_and_stroke); Canvas.drawrect (rect, mpaint);}}
The code to implement the Ontouchlistener Listener and Motionevent event handling for view in the activity class is as follows:

Package Com.example.matrixdemo;import Android.app.activity;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.point;import Android.os.bundle;import Android.util.Log; Import Android.view.menu;import Android.view.motionevent;import Android.view.view;import Android.view.view.ontouchlistener;public class Mainactivity extends Activity implements Ontouchlistener {public static Final int scale_mode = 4;public static final int translation_mode = 2;public static final int null_mode = 1;private Myimag Eview myview;private int mode; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Setcontentview (R.layout.activity_main); Startmyimageview ();} private void Startmyimageview () {MyView = (Myimageview) This.findviewbyid (R.id.myview); Bitmap Bitmap = Bitmapfactory.decoderesource (This.getresources (), r.drawable.flower_001); Myview.setbitmap (BITMAP); Myview.setontouchlistener (this); Myview.invalidate ();} @Overridepublic Boolean ONcreateoptionsmenu (Menu menu) {getmenuinflater (). Inflate (R.menu.main, menu); return true;} @Overridepublic Boolean OnTouch (view view, Motionevent event) {log.i ("Touch Event", "Touch x =" + Event.getx ()); switch (Mo Tionevent.action_mask & Event.getaction ()) {case MotionEvent.ACTION_DOWN:mode = Translation_mode; Myview.setstartpoint (new Point (int) event.getx (), (int) event.gety ())); Break;case motionevent.action_pointer_up: Case MotionEvent.ACTION_OUTSIDE:case MotionEvent.ACTION_UP:mode = Null_mode;myview.savepreviousresult (); break;case MotionEvent.ACTION_POINTER_DOWN:mode = scale_mode;myview.setinitdistance (Calculatedistance (event)); break;case MotionEvent.ACTION_MOVE:if (mode = = Scale_mode) {Float dis = calculatedistance (event); myview.zoomin (dis);} else if (mode = = Translation_mode) {myview.setmovepoint (new point (int) event.getx (), (int) event.gety ()));} ELSE{LOG.I ("Unknow mode Tag", "Do nothing ..."); break;} Myview.invalidate (); return true;} Private float Calculatedistance (Motionevent event) {FLOat dx = event.getx (0)-event.getx (1), Float dy = event.gety (0)-event.gety (1), Float distance = (float) math.sqrt (DX*DX + Dy*dy); return distance;}}
Three: The operating effect is as follows


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Zoom in and drag in custom view with bitmap in Android

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.