Zoom in and drag in custom view with bitmap in Android

Source: Internet
Author: User
Tags gety

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

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.