English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
概述:通过自定义ImageView控件,在xml布局里面调用自定的组件实现图片的缩放。
/** * 自定义的ImageView控制,可对图片进行多点触控缩放和拖动 * * @author qiuwanyong */ public class MyImageView extends ImageView { /** * 初始化状态常量 */ public static final int STATUS_INIT = 1; /** * 图片放大状态常量 */ public static final int STATUS_ZOOM_OUT = 2; /** * 图片缩小状态常量 */ public static final int STATUS_ZOOM_IN = 3; /** * 图片拖动状态常量 */ public static final int STATUS_MOVE = 4; /** * 用于对图片进行移动和缩放变换的矩阵 */ private Matrix matrix = new Matrix(); /** * das anzuzeigende Bitmap-Objekt */ private Bitmap sourceBitmap; /** * 记录当前操作的状态,可选值为STATUS_INIT、STATUS_ZOOM_OUT、STATUS_ZOOM_IN和STATUS_MOVE */ private int currentStatus; /** * Die Breite des ZoomImageView-Steuerlements */ private int width; /** * Die Höhe des ZoomImageView-Steuerlements */ private int height; /** * Zeichnet den x-Wert des Mittelpunkts auf, wenn beide Finger gleichzeitig auf dem Bildschirm platziert sind. */ private float centerPointX; /** * Zeichnet den y-Wert des Mittelpunkts auf, wenn beide Finger gleichzeitig auf dem Bildschirm platziert sind. */ private float centerPointY; /** * Zeichnet die aktuelle Breite des Bildes auf, dieser Wert ändert sich zusammen mit der Vergrößerung des Bildes. */ private float currentBitmapWidth; /** * Zeichnet die aktuelle Höhe des Bildes auf, dieser Wert ändert sich zusammen mit der Vergrößerung des Bildes. */ private float currentBitmapHeight; /** * Zeichnet den x-Wert der letzten Fingerbewegung auf. */ private float lastXMove = -1; /** * Zeichnet den y-Wert der letzten Fingerbewegung auf. */ private float lastYMove = -1; /** * Zeichnet den Verschiebungsvalue der Finger in der x-Achse auf. */ private float movedDistanceX; /** * Zeichnet den Verschiebungsvalue der Finger in der y-Achse auf. */ private float movedDistanceY; /** * Zeichnet den horizontalen Verschiebungsvalue des Bildes in der Matrix auf. */ private float totalTranslateX; /** * Zeichnet den vertikalen Verschiebungsvalue des Bildes in der Matrix auf. */ private float totalTranslateY; /** * Zeichnet das Verhältnis der Gesamtkonvergenz des Bildes in der Matrix auf. */ private float totalRatio; /** * Zeichnet das Verhältnis der Vergrößerung durch das Verschieben der Finger auf. */ private float scaledRatio; /** * Zeichnet das Verhältnis der Vergrößerung des Bildes bei der Initialisierung auf. */ private float initRatio; /** * Zeichnet die Distanz zwischen den letzten beiden Fingern auf. */ private double lastFingerDis; /** * Konstruktor von ZoomImageView, setzt den aktuellen Betriebsstatus auf STATUS_INIT. * * @param context * @param attrs */ public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); currentStatus = STATUS_INIT; } /** * Legt das anzuzeigende Bild fest. * * @param bitmap * das anzuzeigende Bitmap-Objekt */ 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) { // erhalten Sie die Breite und Höhe des ZoomImageView width = getWidth(); height = getHeight(); } } @SuppressLint("NewApi") @Override public boolean onTouchEvent(MotionEvent event) { if (initRatio == totalRatio) { getParent().requestDisallowInterceptTouchEvent(false); } else { getParent().requestDisallowInterceptTouchEvent(true); } switch (event.getActionMasked()) { case MotionEvent.ACTION_POINTER_DOWN: if (event.getPointerCount() == 2) { // wenn zwei Finger auf dem Bildschirm gedrückt werden, berechnen Sie den Abstand zwischen den Fingern lastFingerDis = distanceBetweenFingers(event); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_MOVE: if (event.getPointerCount() == 1) { // es ist nur in Zustand der Zugigung, wenn ein Finger auf dem Bildschirm bewegt wird 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; // prüfen Sie die Grenzen, es ist nicht erlaubt, das Bild aus den Grenzen zu ziehen 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; } // Aufruf der onDraw()-Methode zum Zeichnen des Bildes invalidate(); lastXMove = xMove; lastYMove = yMove; } else if (event.getPointerCount() == 2) { // Wenn zwei Finger auf dem Bildschirm gleichzeitig bewegt werden, ist der Zoom-Modus aktiv centerPointBetweenFingers(event); double fingerDis = distanceBetweenFingers(event); if (fingerDis > lastFingerDis) { currentStatus = STATUS_ZOOM_OUT; } else { currentStatus = STATUS_ZOOM_IN; } // Durchführung der Vergrößerungsunterschriftenprüfung, die das Bild nur vergrößert werden4mal, kann das Bild smallest auf die Initialproportion verkleinert werden 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; } // Aufruf der onDraw()-Methode zum Zeichnen des Bildes invalidate(); lastFingerDis = fingerDis; } } break; case MotionEvent.ACTION_POINTER_UP: if (event.getPointerCount() == 2) { // Während der Finger den Bildschirm verlässt, wird der vorläufige Wert wiederhergestellt lastXMove = -1; lastYMove = -1; } break; case MotionEvent.ACTION_UP: // Während der Finger den Bildschirm verlässt, wird der vorläufige Wert wiederhergestellt lastXMove = -1; lastYMove = -1; break; default: break; } return true; } /** * Bestimmen Sie basierend auf dem Wert von currentStatus, welche Art der Zeichnungsoperation das Bild durchführt. */ @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; } } /** * Führen Sie eine Skalierung des Bildes durch. * * @param canvas */ private void zoom(Canvas canvas) { matrix.reset(); // Vergrößern Sie das Bild nach dem Gesamtskalierungsfaktor matrix.postScale(totalRatio, totalRatio); float scaledWidth = sourceBitmap.getWidth() * totalRatio; float scaledHeight = sourceBitmap.getHeight() * totalRatio; float translateX = 0f; float translateY = 0f; // Wenn die Breite des aktuellen Bildes kleiner als die Bildschirmbreite ist, wird horizontal auf die Horizontale des Bildschirmzentrums skaliert. Andernfalls wird auf die Horizontale des Mittelpunkts der beiden Finger skaliert if (currentBitmapWidth < width) { translateX = (width - scaledWidth) / 2f; } else { translateX = totalTranslateX * scaledRatio + centerPointX * (1 - scaledRatio); // Führen Sie eine Grenzprüfung durch, um sicherzustellen, dass das Bild nach dem Skalieren im horizontalen Bereich des Bildschirms nicht verschoben wird if (translateX > 0) { translateX = 0; } else if (width - translateX > scaledWidth) { translateX = width - scaledWidth; } } // Wenn die Höhe des aktuellen Bildes kleiner als die Bildschirmhöhe ist, wird vertikal auf die Vertikale des Bildschirmzentrums skaliert. Andernfalls wird auf die Vertikale des Mittelpunkts der beiden Finger skaliert. if (currentBitmapHeight < height) {}} translateY = (height - scaledHeight) / 2f; } else { translateY = totalTranslateY * scaledRatio + centerPointY * (1 - scaledRatio); // Führe die Grenzprüfung durch, um sicherzustellen, dass das Bild nach der Skalierung nicht aus dem Bildschirmbereich im vertikalen Bereich hinausgeht if (translateY > 0) { translateY = 0; } else if (height - translateY > scaledHeight) { translateY = height - scaledHeight; } } // Verschiebe das Bild nach der Skalierung, um sicherzustellen, dass der Mittelpunkt nach der Skalierung unverändert bleibt matrix.postTranslate(translateX, translateY); totalTranslateX = translateX; totalTranslateY = translateY; currentBitmapWidth = scaledWidth; currentBitmapHeight = scaledHeight; canvas.drawBitmap(sourceBitmap, matrix, null); } /** * Führe den Verschiebungsprozess des Bildes aus * * @param canvas */ private void move(Canvas canvas) { matrix.reset(); // Berechne den Gesamtabstand basierend auf dem Verschiebungsabstand des Fingers float translateX = totalTranslateX + movedDistanceX; float translateY = totalTranslateY + movedDistanceY; // Skaliere das Bild zunächst basierend auf dem bestehenden Skalierungsfaktor matrix.postScale(totalRatio, totalRatio); // Verschiebe basierend auf dem Verschiebungsabstand matrix.postTranslate(translateX, translateY); totalTranslateX = translateX; totalTranslateY = translateY; canvas.drawBitmap(sourceBitmap, matrix, null); } /** * Führe Initialisierungsoperationen für das Bild durch, einschließlich der Zentrierung des Bildes und des Komprimierens des Bildes, wenn das Bild größer als der Bildschirm ist. * * @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) {}} // Wenn die Breite des Bildes größer als die Bildschirmbreite ist, komprimiere das Bild proportional, damit es vollständig angezeigt werden kann float ratio = width / (bitmapWidth * 1.0f); matrix.postScale(ratio, ratio); float translateY = (height - (bitmapHeight * ratio)) / 2f; // Verschiebe im vertikalen Koordinatenbereich, um sicherzustellen, dass das Bild zentriert angezeigt wird matrix.postTranslate(0, translateY); totalTranslateY = translateY; totalRatio = initRatio = ratio; } else { // Wenn die Höhe des Bildes größer als die Bildschirmhöhe ist, komprimiere das Bild proportional, damit es vollständig angezeigt werden kann float ratio = height / (bitmapHeight * 1.0f); matrix.postScale(ratio, ratio); float translateX = (width - (bitmapWidth * ratio)) / 2f; // Verschiebe im horizontalen Koordinatenbereich, um sicherzustellen, dass das Bild zentriert angezeigt wird matrix.postTranslate(translateX, 0); totalTranslateX = translateX; totalRatio = initRatio = ratio; } currentBitmapWidth = bitmapWidth * initRatio; currentBitmapHeight = bitmapHeight * initRatio; } else { // Wenn die Breite und Höhe des Bildes beide kleiner als die Bildschirmbreite und -höhe sind, zeige das Bild direkt zentriert an 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); } } /** * Berechne den Abstand zwischen den beiden Fingern. * * @param event * @return Der Abstand zwischen den beiden Fingern */ @SuppressLint("NewApi") private double distanceBetweenFingers(MotionEvent event) { float disX = Math.abs(event.getX(0) - event.getX(1)); float disY = Math.abs(event.getY(0) - event.getY(1)); return Math.sqrt(disX * disX + disY * disY); } /** * Berechnung der Koordinaten des Mittelpunkts zwischen zwei Fingern. * * @param event */ @SuppressLint("NewApi") private void centerPointBetweenFingers(MotionEvent event) { float xPoint0 = event.getX(0); float yPoint0 = event.getY(0); float xPoint1 = event.getX(1); float yPoint1 = event.getY(1); centerPointX = (xPoint0 + xPoint1) / 2; centerPointY = (yPoint0 + yPoint1) / 2; } }
Aufruf in der Anordnung
Der nachstehende Code, der von mir vorgestellt wird, zeigt, wie man die Skalierung und das Verschieben von Bildern durch Anpassung des ImageView-Steuerlements in Android umsetzt. Ich hoffe, dass dieser Code Ihnen weiterhilft. Wenn Sie Fragen haben, hinterlassen Sie bitte eine Nachricht, ich werde mich umgehend um eine Antwort kümmern. Ich danke auch sehr für Ihre Unterstützung für die Website yellowschool.de!
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem jeweiligen Urheber. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt keine rechtlichen Verantwortlichkeiten. Wenn Sie verdächtige Urheberrechtsinhalte finden, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @, wenn Sie eine Beschwerde einreichen, und fügen Sie relevante Beweise bei. Bei nachgewiesener Infringement wird dieser Inhalt sofort gelöscht.)