android-layout - programacion - redimensionar imagenes android studio
¿Por qué mi imagen se recorta después de escalar? (2)
Después de actualizar la escala, debe invalidar () y requestLayout () las vistas.
targetView.invalidate();
targetView.requestLayout();
Por lo general, calculo la escala de manera diferente para las imágenes. Podría intentar escalar la vista de la imagen utilizando el tipo de escala MATRIX. Deberá conocer el tamaño de su DPI enlazado.
// Get the scaled DPI
int boundBoxInDp = getResources().getDisplayMetrics().densityDpi * scaleFactor
// Determine how much to scale: the dimension requiring less scaling is
// closer to its side. This way the image always stays inside your
// bound AND either x/y axis touches the bound but neither will go over.
float xScale = ((float) boundBoxInDp) / newWidth;
float yScale = ((float) boundBoxInDp) / newHeight;
float scale = (xScale <= yScale) ? xScale : yScale;
// scale using our calculated scale
targetView.setScaleX(scale);
targetView.setScaleY(scale);
En cuanto a su segunda pregunta sobre el Pivot. Probablemente deba establecerse en el centro del área de desplazamiento visible. El área desplazable se debe aumentar cuando cambie el tamaño de la imagen, ya que está usando FIT_CENTER
;
Estoy teniendo un problema extraño. Escalo una imagen y, mientras que la escala funciona correctamente, la imagen siempre se recorta. Intenté diferentes tipos de básculas: las cosas cambiaron pero nunca pude hacerlo funcionar.
Para que quede claro, esto es lo que necesito resolver: 1. Tengo un HorizontalScrollView
alrededor de ImageView
y un ScrollView
alrededor de HorizontalView
. 2. Me desplazo (usando scrollTo
de ambas vistas de desplazamiento) y, luego de cierto evento, acercamiento. 3. Lo que me gustaría que ocurra es que ImageView
escala alrededor de mi posición de desplazamiento actual.
Aquí está el diseño:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:scaleType="fitCenter" />
</HorizontalScrollView>
</ScrollView>
</FrameLayout>
Y aquí está el código de escala ( originalWidth
/ originalHeight
se calculan a escala de 1
; targetView
apunta a ImageView
):
public synchronized void changeScale(float newScaleFactor) {
this.scaleFactor = Math.max(min_zoom, Math.min(newScaleFactor, max_zoom));
if (targetView != null && originalWidth > 0) {
int newWidth = (int)(originalWidth * scaleFactor);
int newHeight = (int)(originalHeight * scaleFactor);
onScaleChanged(targetView, scaleFactor, newWidth, newHeight);
}
}
public void onScaleChanged(View targetView, float scaleFactor, int newWidth, int newHeight) {
ViewGroup.LayoutParams layoutParams = targetView.getLayoutParams();
layoutParams.width = newWidth;
layoutParams.height = newHeight;
// This is needed to increase the pane size (rather than zoom within the initial layout)
targetView.setLayoutParams(layoutParams);
// Tell the system to recalculate the layout
targetView.requestLayout();
// This is needed to specify the center of scaling
HorizontalScrollView horizontalScrollView = (HorizontalScrollView)targetView.getParent();
ScrollView vertScrollView = (ScrollView)horizontalScrollView.getParent();
// ~~~ the pivot points are probably wrong
targetView.setPivotX(horizontalScrollView.getScrollX() * scaleFactor);
targetView.setPivotY(vertScrollView.getScrollY() * scaleFactor);
// This is needed for actual zooming
targetView.setScaleX(scaleFactor);
targetView.setScaleY(scaleFactor);
};
public void zoomIn(float scaleDelta) {
changeScale(scaleFactor + scaleDelta);
}
public void zoomOut(float scaleDelta) {
changeScale(scaleFactor - scaleDelta);
}
Pregunta 1: ¿Cómo evito el recorte? No puedo encontrar la combinación correcta de scaleType
y el cambio de tamaño del diseño.
Pregunta 2: Cuando uso setScaleX
/ setScaleY
, ¿debería calcularse mi pivote después de aplicar el nuevo factor de escala o el enrutador se ocupa de eso automáticamente?
Vea este artículo para el código que funciona bastante bien. Me deshice de HorizontalScrollView y ScrollView y adjunté este PanAndZoomListener a mi FrameLayout y, a partir de ese momento, todos fueron arcoíris y unicornios.
Traté de hacer lo mismo que tú, pero sin éxito. Parece que puede desplazarse por un ImageView sin utilizar HorizontalScrollView y ScrollView. Aún no tengo claro qué es lo que lo hace posible, pero me inclino por el uso de la matriz de imágenes (como en, setImageMatrix en ImageView) o posiblemente por el uso de MarginLayoutParams. Al mirar el código fuente de la Galería de imágenes disponible en Android, veo un uso intensivo de Matrix. Lamentablemente, la documentación sobre esto parece ser bastante ligera en mi opinión.
Otras personas lo han descubierto, así que conecta el PanAndZoomListener y listo. Eso fue lo que hice.