Android zoom in and drag bitmap in custom view
One: Basic realization ideas
implementation of custom view– based on view class Myimageview class. complete the Ontouchlistener interface in the activity class using view to enable touch event monitoring of Custom view
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. zooming and panning transformation of bitmap on view based on matrix object implementation
Bitmap Update and display of 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.
Myimageview description of the important method of the class:
initparameters () Initialize all parameters that need to be used
Setstartpoint () Set the start 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 that the bitmap object needs to translate SX, SY. It also includes a check code that ensures that the image does not cross the view boundary.
Savepreviousresult () to save the current panning data, the next time you can continue panning the bitmap object on a secondary basis.
ZoomIn () based on Euclidean distance between two points, the magnification is obtained by comparing the initial distance to achieve the magnification of the bitmap on the View object.
Matrix.postscale the method and Matrix.posttranslate method can translate and enlarge without changing the bitmap object itself.
Ontouchlistener supports the following touch event handling :
Action_down event, recording translation start point
action_up event, ending translation event handling
Action_move events, record translation points, calculate distance from start point, achieve bitmap translation, calculate distance between two points at multi-touch, achieve image amplification
Action_pointer_down event, calculate 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
Two: Code implementation
The use of custom view in layout XML is as follows:
<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 implementation code for the custom view class 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;// panning start point and move Point private point startpoint;private point movepoint;private float initdistance;// record the current translation distance private int sx;private int sy;// Bao Cunping Move State private int oldsx;private int oldsy;// 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 () {// Initialize 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 (); Float height = this.getheight ();// Initial reduction 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 = bitmap.getheight ();float width = This.getwidth (); Float height = this.getheight ();// get scale ratewidthrate = (width / iw ) * rate;heightRate = (HEIGHT&NBSP;/&NBSP;IH) * rate;// make it same as view sizefloat iwr = (width / iw );float ihr = (HEIGHT&NBSP;/&NBSP;IH); if (iwr >= widthrate) {widthRate = (width / iw );} if (ihr >= heightrate) {heightrate = (HEIGHT&NBSP;/&NBSP;IH);} go to centeroldsx = (int) ((WIDTH&NBSP;-&NBSP;WIDTHRATE&NBSP;*&NBSP;IW) / &NBSP;2);oldsy = (int) ((HEIGHT&NBSP;-&NBSP;HEIGHTRATE&NBSP;*&NBSP;IH) / 2);} Public void setmovepOint (Point movepoint) {this.movepoint = movepoint;sx = this.movepoint.x - this.startpoint.x;sy = this.movepoint.y - this.startpoint.y;float iw = bitmap.getwidth (); Float ih = bitmap.getheight ();// Detect Edge int deltax = ( int) ((WIDTHRATE&NBSP;*&NBSP;IW) - this.getwidth ());int deltay = (int) ((heightRate &NBSP;*&NBSP;IH) - this.getheight ()); if ((SX&NBSP;+&NBSP;THIS.OLDSX) >= 0) {THIS.OLDSX = 0;sx = 0;} Else if ((SX&NBSP;+&NBSP;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 reduction 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);}}}
mainactivity code 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 myimageview 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 (motionevent.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;}}
Run as follows:
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M02/75/70/wKiom1Y48DmToNmBAADcPxGGOu0808.jpg "title=" Result.png "alt=" Wkiom1y48dmtonmbaadcpxggou0808.jpg "/>
This article is from the "Stray Fish" blog, please be sure to keep this source http://gloomyfish.blog.51cto.com/8837804/1709451
Zoom in and drag in custom view with bitmap in Android