Knowledge points involved in Android multi-touch
1、ScaleGestureDetector
2、OnScaleGestureListener
3、Matrix
4、OnTouchListener
There are four knowledge points that need to be understood. It should be noted that Matrix is a one-dimensional array in memory, and Matrxi that controls pictures is a 3X3 matrix, which is a one-dimensional array of size 9 in memory.
Realize multi-touch and freely change pictures
1. Inheritance based on ImageView
2. Because the relevant attributes need to be obtained after the image is loaded, the OnGlobalLayoutListener interface is implemented and the method onGlobalLayout is implemented.
Register the OnGlobalLayoutListener interface:
@Override protected void onAttachedToWindow() { (); //Register OnGlobalLayoutListener getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override protected void onDetachedFromWindow() { (); //Login onGlobalLayoutListener getViewTreeObserver().removeOnGlobalLayoutListener(this); }
Implement the onGlobalLayout method
@Override public void onGlobalLayout() { //Because you need to obtain the width and height of the image when the load is completed, and then let the width and height of the image adapt to the width and height of the control. isOnce is only processed when the first load is loaded. if (isOnce) { //Next step 3 Get relevant attributes and process them isOnce = false; } }
3、
//Get the width and height of the control int width = getWidth(); int height = getHeight(); //Get pictures Drawable drawable = getDrawable(); if (null == drawable) { return; } //Get the width and height of the picture **Get according to these two methods of drawable int dw = (); int dh = (); //Define an image scaling value float scale = 1.0f; Next is based on the width and height of the picture Width and height of the control Go to set thisscalevalue //When the width of the picture is larger than the width of the control, the height of the picture is smaller than the height of the controlif (dw > width && dh < height) { scale = width * 1.0f / dw; } //When the width of the picture is smaller than the width of the control, the height of the picture is larger than the height of the controlif (dw < width && dh > height) { scale = height * 1.0f / dh; } if ((dw > width && dh > height) || (dw < width && dh < height)) { scale = ((width * 1.0f / dw), (height * 1.0f / dh)); } //Initialize the three scaled values mInitScale = scale;//Scaling value under normal circumstances mMidScale = scale * 2; // mMaxScale = scale * 4;//Maximum scaling value //Load the image initialization to the center of the control // Calculate the offset value that needs to be moved horizontally and vertically float dx = getWidth() / 2f - dw / 2f; float dy = getHeight() / 2f - dh / 2f; //Use matrix to control the translation and zoom of the picture (dx, dy); // When scaling, specify the scaling reference point (mInitScale, mInitScale, getWidth() / 2f, getHeight() / 2f); //Change ImageView by setting Matrix setImageMatrix(mMatrix);
4. Next is ScaleGestureDetector
//Initialize this is the OnScaleGestureListener object mScaleGestureDetector = new ScaleGestureDetector(context, this); //To manipulate touch events through ScaleGestureDetector, you must also implement the OnTouchListener interface and implement the onTouch method, in which the touch event is passed to the mScaleGestureDetector object. @Override public boolean onTouch(View view, MotionEvent motionEvent) { //Pass the touch event to ScaleGesture (motionEvent); return true; } //Set up the monitoring setOnTouchListener(this);
5. Important methods in OnScaleGestureListener
//Use ScaleGestureListener to implement multi-touch@Override public boolean onScale(ScaleGestureDetector scaleGestureDetector) { if (null == getDrawable()) { return true; } //Next step 6 processing return true; }
6、
//Scaling //Get the current image scaling scale float scale = getCurrentScale(); //Get the scaling factor float scaleFactor = (); // When the scaling value reaches the maximum and minimum scaleFactor>1 means zooming in <1 means zooming in if ((scale < mMaxScale && scaleFactor > 1.0f) || scale > mInitScale && scaleFactor < 1.0f) { if (scale * scaleFactor < mInitScale) { scaleFactor = mInitScale / scale; } else if (scale * scaleFactor > mMaxScale) { scaleFactor = mMaxScale / scale; } } //Set the zoom of the picture according to the scaling factor Scaling according to the center of the multi-point (), () The zoom center point must be the center point touched by the finger (scaleFactor, scaleFactor, (), ()); //Because the center point of the zoom will change, you need to control the boundary processing of the image*** If you do not process, the center point will change according to the position of your finger, and the position of the image will be incorrect. checkoutBounds(); //Next step 7 setImageMatrix(mMatrix);
7、checkoutBounds()
private void checkoutBounds() { //The size and coordinates of the zoomed image must be obtained through the matrix Drawable drawable = getDrawable(); if (null != drawable) { RectF rectF = getScaleMatrix(drawable); //Next step 8 //Get the width and height of the control int width = getWidth(); int height = getHeight(); //Declare x y offset value If it deviates from the control, it needs to be moved back float detalX = 0; float detalY = 0; if (() >= width) { //The width of the picture is greater than or equal to the width of the control. In order to leave a white edge in width, calculate the offset value that should be moved left and right. if (0 < ) { //If the left is blank, it should be like moving left detalX = -; } else if ( < width) { detalX = width - ; } } //Height control if (() >= height) { if (0 < ) { detalY = -; } else if ( < height) { detalY = height - ; } } //If the image width and height are smaller than the control width and height, let the image be displayed in the center if (() < width) { // Calculate the offset value detalX = width / 2f - + () / 2f; } if (() < height) { detalY = height / 2f - + () / 2f; } (detalX, detalY); }
8. getScaleMatrix(drawable) This method can also be imitated in other places
//Get the four vertex coordinates of the scaled picture through the matrixpublic RectF getScaleMatrix(Drawable drawable) { Matrix matrix = mMatrix; //The four point coordinates of the picture RectF rectF = new RectF(0, 0, (), ()); (rectF); return rectF; }
Through this control, you can become familiar with the implementation of multi-touch and the knowledge of graphics matrix
Demo Address:ZoomImageView
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.