English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Aperçu : en personnalisant le contrôle ImageView, appeler le composant personnalisé dans le fichier xml de conception pour réaliser le zoom de l'image.
/** * Contrôle ImageView personnalisé, permettant le zoom et le déplacement multipoints sur l'image * * @author qiuwanyong */ public class MyImageView extends ImageView { /** * Constante de statut d'initialisation */ public static final int STATUS_INIT = 1; /** * Constante de statut d'agrandissement de l'image */ public static final int STATUS_ZOOM_OUT = 2; /** * Constante de statut de réduction de l'image */ public static final int STATUS_ZOOM_IN = 3; /** * Constante de statut de glisser-déposer de l'image */ public static final int STATUS_MOVE = 4; /** * Matrice utilisée pour les transformations de déplacement et de zoom sur l'image */ private Matrix matrix = new Matrix(); /** * l'objet Bitmap à afficher */ private Bitmap sourceBitmap; /** * Enregistre l'état de l'opération actuelle, les valeurs possibles sont STATUS_INIT, STATUS_ZOOM_OUT, STATUS_ZOOM_IN et STATUS_MOVE */ private int currentStatus; /** * La largeur du contrôle ZoomImageView */ private int width; /** * La hauteur du contrôle ZoomImageView */ private int height; /** * Enregistrer la coordonnée horizontale du point central lorsque les deux doigts sont placés sur l'écran */ private float centerPointX; /** * Enregistrer la coordonnée verticale du point central lorsque les deux doigts sont placés sur l'écran */ private float centerPointY; /** * Enregistrer la largeur actuelle de l'image, cette valeur changera lorsque l'image sera zoomée */ private float currentBitmapWidth; /** * Enregistrer la hauteur actuelle de l'image, cette valeur changera lorsque l'image sera zoomée */ private float currentBitmapHeight; /** * Enregistrer la coordonnée horizontale du déplacement du doigt précédent */ private float lastXMove = -1; /** * Enregistrer la coordonnée verticale du déplacement du doigt précédent */ private float lastYMove = -1; /** * Enregistrer la distance de déplacement du doigt en coordonnées horizontales */ private float movedDistanceX; /** * Enregistrer la distance de déplacement du doigt en coordonnées verticales */ private float movedDistanceY; /** * Enregistrer la valeur de décalage horizontal de l'image sur la matrice */ private float totalTranslateX; /** * Enregistrer la valeur de décalage vertical de l'image sur la matrice */ private float totalTranslateY; /** * Enregistrer le rapport de zoom total de l'image sur la matrice */ private float totalRatio; /** * Enregistrer le rapport de zoom causé par le déplacement des doigts */ private float scaledRatio; /** * Enregistrer le rapport de zoom initial de l'image */ private float initRatio; /** * Enregistrer la distance entre les deux doigts précédents */ private double lastFingerDis; /** * Constructeur de ZoomImageView, configure l'état d'opération actuel à STATUS_INIT. * * @param context * @param attrs */ public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); currentStatus = STATUS_INIT; } /** * Définir l'image à afficher. * * @param bitmap * l'objet Bitmap à afficher */ public void setImageBitmap(Bitmap bitmap) { sourceBitmap = bitmap; invalidate(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { // obtenir respectivement la largeur et la hauteur de ZoomImageView width = getWidth(); height = getHeight(); } } @SuppressLint("NewApi") @Override public boolean onTouchEvent(MotionEvent event) { if (initRatio == totalRatio) { getParent().requestDisallowInterceptTouchEvent(false); } getParent().requestDisallowInterceptTouchEvent(true); } switch (event.getActionMasked()) { case MotionEvent.ACTION_POINTER_DOWN: if (event.getPointerCount() == 2) { // quand deux doigts sont appuyés sur l'écran, calculer la distance entre les deux doigts lastFingerDis = distanceBetweenFingers(event); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_MOVE: if (event.getPointerCount() == 1) { // l'état de glisser est actif uniquement lorsque le doigt unique est en mouvement sur l'écran float xMove = event.getX(); float yMove = event.getY(); if (lastXMove == -1 && lastYMove == -1) { lastXMove = xMove; lastYMove = yMove; } currentStatus = STATUS_MOVE; movedDistanceX = xMove - lastXMove; movedDistanceY = yMove - lastYMove; // effectuer des vérifications de bornes, il n'est pas permis de faire glisser l'image au-delà des bornes if (totalTranslateX + movedDistanceX > 0) {}} movedDistanceX = 0; } else if (width - (totalTranslateX + movedDistanceX) > currentBitmapWidth) { movedDistanceX = 0; } if (totalTranslateY + movedDistanceY > 0) { movedDistanceY = 0; } else if (height - (totalTranslateY + movedDistanceY) > currentBitmapHeight) { movedDistanceY = 0; } // Appeler la méthode onDraw() pour dessiner l'image invalidate(); lastXMove = xMove; lastYMove = yMove; } else if (event.getPointerCount() == 2) { // L'état de zoom est actif lorsque deux doigts glissent sur l'écran centerPointBetweenFingers(event); double fingerDis = distanceBetweenFingers(event); if (fingerDis > lastFingerDis) { currentStatus = STATUS_ZOOM_OUT; } currentStatus = STATUS_ZOOM_IN; } // Vérifier le facteur de zoom, la taille maximale autorisée est d'agrandir l'image4fois, la plus petite taille peut être réduite à la proportion initiale if ((currentStatus == STATUS_ZOOM_OUT && totalRatio < 4 * initRatio) || (currentStatus == STATUS_ZOOM_IN && totalRatio > initRatio)) { scaledRatio = (float) (fingerDis / lastFingerDis); totalRatio = totalRatio * scaledRatio; if (totalRatio > 4 * initRatio) { totalRatio = 4 * initRatio; } else if (totalRatio < initRatio) { totalRatio = initRatio; } // Appeler la méthode onDraw() pour dessiner l'image invalidate(); lastFingerDis = fingerDis; } } break; case MotionEvent.ACTION_POINTER_UP: if (event.getPointerCount() == 2) { // le réglage temporaire est restauré lorsque le doigt quitte l'écran lastXMove = -1; lastYMove = -1; } break; case MotionEvent.ACTION_UP: // le réglage temporaire est restauré lorsque le doigt quitte l'écran lastXMove = -1; lastYMove = -1; break; default: break; } return true; } /** * les opérations de dessin sur l'image sont déterminées en fonction de la valeur de currentStatus. */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); switch (currentStatus) { case STATUS_ZOOM_OUT: case STATUS_ZOOM_IN: zoom(canvas); break; case STATUS_MOVE: move(canvas); break; case STATUS_INIT: initBitmap(canvas); default: if (sourceBitmap != null) { canvas.drawBitmap(sourceBitmap, matrix, null); } break; } } /** * l'image est traitée pour l'ajustement de l'échelle. * * @param canvas */ private void zoom(Canvas canvas) { matrix.reset(); // l'image est réduite selon le rapport total d'ajustement matrix.postScale(totalRatio, totalRatio); float scaledWidth = sourceBitmap.getWidth() * totalRatio; float scaledHeight = sourceBitmap.getHeight() * totalRatio; float translateX = 0f; float translateY = 0f; // Si la largeur de l'image actuelle est inférieure à la largeur de l'écran, l'ajustement horizontal est effectué selon la coordonnée horizontale du centre de l'écran. Sinon, l'ajustement horizontal est effectué selon la coordonnée horizontale du centre des deux doigts. if (currentBitmapWidth < width) { translateX = (width - scaledWidth) / 2f; } translateX = totalTranslateX * scaledRatio + centerPointX * (1 - scaledRatio); // faire la vérification des limites pour s'assurer que l'image ne dévie pas de l'écran après l'ajustement de l'échelle en direction horizontale if (translateX > 0) { translateX = 0; } else if (width - translateX > scaledWidth) { translateX = width - scaledWidth; } } // Si la hauteur de l'image actuelle est inférieure à la hauteur de l'écran, l'ajustement vertical est effectué selon la coordonnée verticale du centre de l'écran. Sinon, l'ajustement vertical est effectué selon la coordonnée verticale du centre des deux doigts. if (currentBitmapHeight < height) { translateY = (height - scaledHeight) / 2f; } translateY = totalTranslateY * scaledRatio + centerPointY * (1 - scaledRatio); // Vérification des limites pour garantir que l'image ne sort pas de l'écran après le zoom en vertical if (translateY > 0) { translateY = 0; } else if (height - translateY > scaledHeight) { translateY = height - scaledHeight; } } // Décalage de l'image après le zoom pour garantir que le point central reste invariable après le zoom matrix.postTranslate(translateX, translateY); totalTranslateX = translateX; totalTranslateY = translateY; currentBitmapWidth = scaledWidth; currentBitmapHeight = scaledHeight; canvas.drawBitmap(sourceBitmap, matrix, null); } /** * Traitement de déplacement de l'image * * @param canvas */ private void move(Canvas canvas) { matrix.reset(); // Calcul de la valeur de décalage totale en fonction de la distance de déplacement du doigt float translateX = totalTranslateX + movedDistanceX; float translateY = totalTranslateY + movedDistanceY; // Ajustement de l'image en fonction du rapport de zoom existant matrix.postScale(totalRatio, totalRatio); // Décalage en fonction de la distance de déplacement matrix.postTranslate(translateX, translateY); totalTranslateX = translateX; totalTranslateY = translateY; canvas.drawBitmap(sourceBitmap, matrix, null); } /** * Opérations d'initialisation de l'image, y compris le centrage de l'image et le redimensionnement de l'image lorsque l'image est plus grande que la largeur ou la hauteur de l'écran. * * @param canvas */ private void initBitmap(Canvas canvas) { if (sourceBitmap != null) { matrix.reset(); int bitmapWidth = sourceBitmap.getWidth(); int bitmapHeight = sourceBitmap.getHeight(); if (bitmapWidth > width || bitmapHeight > height) { if (bitmapWidth - width > bitmapHeight - height) {}} // Lorsque la largeur de l'image est supérieure à la largeur de l'écran, compresser l'image proportionnellement pour qu'elle puisse être affichée intégralement float ratio = width / (bitmapWidth * 1.0f); matrix.postScale(ratio, ratio); float translateY = (height - (bitmapHeight * ratio)) / 2f; // Décaler dans la direction de l'ordonnée pour assurer l'affichage centralisé de l'image matrix.postTranslate(0, translateY); totalTranslateY = translateY; totalRatio = initRatio = ratio; } // Lorsque la hauteur de l'image est supérieure à la hauteur de l'écran, compresser l'image proportionnellement pour qu'elle puisse être affichée intégralement float ratio = height / (bitmapHeight * 1.0f); matrix.postScale(ratio, ratio); float translateX = (width - (bitmapWidth * ratio)) / 2f; // Décaler dans la direction de l'abscisse pour assurer l'affichage centralisé de l'image matrix.postTranslate(translateX, 0); totalTranslateX = translateX; totalRatio = initRatio = ratio; } currentBitmapWidth = bitmapWidth * initRatio; currentBitmapHeight = bitmapHeight * initRatio; } // Lorsque la largeur et la hauteur de l'image sont toutes deux inférieures à la largeur et à la hauteur de l'écran, affichez directement l'image au centre float translateX = (width - sourceBitmap.getWidth()) / 2f; float translateY = (height - sourceBitmap.getHeight()) / 2f; matrix.postTranslate(translateX, translateY); totalTranslateX = translateX; totalTranslateY = translateY; totalRatio = initRatio = 1f; currentBitmapWidth = bitmapWidth; currentBitmapHeight = bitmapHeight; } canvas.drawBitmap(sourceBitmap, matrix, null); } } /** * Calculer la distance entre les deux doigts. * * Calculer les coordonnées du point central entre les deux doigts. * @return La distance entre les deux doigts */ @SuppressLint("NewApi") private double distanceBetweenFingers(MotionEvent event) { float disX = Math.abs(event.getX(0) - event.getX(1event.getY( event.getX( - float disY = Math.abs(event.getY(0)1event.getY( )); * return Math.sqrt(disX + disX * disY } /** * disY); * * Calculer les coordonnées du point central entre les deux doigts. */ @param event @SuppressLint("NewApi") private void centerPointBetweenFingers(MotionEvent event) { float xPoint0 = event.getX(0); float yPoint0 = event.getY(0);1 float xPoint1); float yPoint1 = event.getY(1); centerPointX = (xPoint0 + xPoint1) / 2; centerPointY = (yPoint0 + yPoint1) / 2; } }
Appel dans le layout
Les codes d'implémentation de l'adaptation et du glissement des images par le biais de l'控件 ImageView personnalisé que l'éditeur vous présente ici pour Android, j'espère qu'ils vous seront utiles. Si vous avez des questions, n'hésitez pas à laisser un message, l'éditeur vous répondra rapidement. Nous tenons également à remercier le soutien de la communauté du site de tutoriels d'urlement !
Déclaration : Le contenu de cet article est issu du réseau, propriété de ses auteurs respectifs, contribué et téléversé par les utilisateurs d'Internet, ce site n'en détient pas la propriété, n'a pas fait l'objet d'une édition humaine et n'assume aucune responsabilité juridique. Si vous trouvez du contenu susceptible de violer les droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, le site supprimera immédiatement le contenu suspect de violation de droit d'auteur.)