¿Cómo obtener el ancho y la altura de un android.widget.ImageView?

272
╔══════════════════════════════════════════════╗   ^
 ImageView    ╔══════════════╗                   |
                                               |
               Actual image                    |
                                               |60px height of ImageView
                                               |
                                               |
              ╚══════════════╝                   |
╚══════════════════════════════════════════════╝   
<------------------------------------------------>
                   90px width of ImageView

Tengo una vista de imagen con un alto y ancho predeterminados, las imágenes se almacenan en db y quiero escalar la imagen de acuerdo con el ancho de altura de la vista de imagen. Como no quiero que dé valores predeterminados porque cada vez que cambio su altura y ancho también tengo que cambiarlo en el código.

Estoy tratando de obtener la altura y el ancho de ImageView, pero me devuelven 0 en ambos casos.

int height = ((ImageView) v.findViewById(R.id.img_ItemView)).getHeight();

esto me devuelve 0 incluso si tiene altura y ancho predeterminados

ARIZONA_
fuente
«Como no quiero dar valores predeterminados porque cada vez que cambio su altura y ancho también tengo que cambiarlo en el código», ¿cuál puede cambiar? la vista de imagen o las imágenes almacenadas?
Pedro Loureiro el
no puedes simplemente usar android:scaleType="centerInside"?
bigstones el
2
@ Nightcracker: Eso no es ASCII.
Joey
77
@ Јοеу Cuando dije "ASCII" quise decir "arte ASCII", que abarca más arte que el que consiste simplemente en el conjunto de caracteres ASCII.
orlp
1
Esto no responde directamente a la pregunta, pero si se pregunta por qué getHeight () / getWidth () devuelve 0, siempre devolverá 0 si llama a esos métodos antes de que la vista se haya "dibujado", es decir, si fuera a llame a estos métodos en onCreate () devolvería 0
audiojared

Respuestas:

222

Mi respuesta a esta pregunta podría ayudarte:

int finalHeight, finalWidth;
final ImageView iv = (ImageView)findViewById(R.id.scaled_image);
final TextView tv = (TextView)findViewById(R.id.size_label);
ViewTreeObserver vto = iv.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    public boolean onPreDraw() {
        iv.getViewTreeObserver().removeOnPreDrawListener(this);
        finalHeight = iv.getMeasuredHeight();
        finalWidth = iv.getMeasuredWidth();
        tv.setText("Height: " + finalHeight + " Width: " + finalWidth);
        return true;
    }
});

Luego puede agregar su trabajo de escalado de imágenes desde el método onPreDraw ().

Kevin Coppock
fuente
8
Muy buen código hermano y lógico +1 para eso. también puede lograr esto configurando la propiedad ImageView android: ajustarViewBounds = "true" en true :)
AZ_
oye, pero al depurar el puntero no te vayas minside onPreDraw (). ¿Por qué es así?
Geetanjali
3
Creo que necesita agregar vto.removeOnPreDrawListener (esto); line inside onPreDraw ()
sagus_helgy
1
@ KK_07 ver la edición según el comentario del Sufferer. Solo tiene que eliminar el oyente una vez que haya terminado con él.
Kevin Coppock
66
¿Cómo asigna valores a finalHeight y finalWidth dentro de una clase interna sin hacerlos finales?
Chris
29

Acabo de configurar esta propiedad y ahora el sistema operativo Android se encarga de todo.

android: ajustarViewBounds = "verdadero"

Use esto en su layout.xml donde ha plantado su ImageView: D

ARIZONA_
fuente
44
@jww Realmente no respondo a los votantes negativos: p, Primero lea sobre getWidth y getMeasured en la documentación de Android. luego ven y baja votar personas.
AZ_
27

Podría obtener el ancho y la altura de la imagen por su dibujo;

int width = imgView.getDrawable().getIntrinsicWidth();
int height = imgView.getDrawable().getIntrinsicHeight();
Rashid
fuente
14

La razón por la cual las dimensiones de ImageView son 0 es porque cuando las consulta, la vista aún no ha realizado los pasos de diseño y medición. Solo le dijo a la vista cómo se "comportaría" en el diseño, pero aún no calculó dónde colocar cada vista.

¿Cómo decide el tamaño que se le dará a la vista de imagen? ¿No puede simplemente usar una de las opciones de escala implementadas de forma nativa?

Pedro Loureiro
fuente
Le di altura y ancho predeterminados a ImageView pero cuando trato de ponerlos en el código me devuelve 0. Creo que primero tengo que inflar ImageView. pero como
AZ_
Abordo eso en mi respuesta. Léelo de nuevo :) Creo que tu punto de vista ya está inflado. ¿Puedes verlo? si puedes, entonces está inflado.
Pedro Loureiro
13

Publicar en el hilo de la interfaz de usuario funciona para mí.

final ImageView iv = (ImageView)findViewById(R.id.scaled_image);

iv.post(new Runnable() {
            @Override
            public void run() {
                int width = iv.getMeasuredWidth();
                int height = iv.getMeasuredHeight();

            }
});
elemento6
fuente
¡De mucha ayuda!
Xavi Jiménez
Incorrecto. Consultar ancho y alto desde la interfaz de usuario no garantiza que esos valores estén listos. La inflación de la vista acaba de terminar en su muestra, pero bien podría ser de otra manera
rommex
6

su archivo xml:

 <ImageView android:id="@+id/imageView"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:src="@drawable/image"
               android:scaleType="fitXY"
               android:adjustViewBounds="true"/>

su archivo java:

ImageView imageView = (ImageView)findViewById(R.id.imageView);
     int width = imageView.getDrawable().getIntrinsicWidth();
     int   height = imageView.getDrawable().getIntrinsicHeight();
omor
fuente
5

Creo que puedes dejar que el sistema operativo Android se encargue de esto por ti. Establezca el tipo de escala en ImageView en fitXYy la imagen que muestra se ajustará al tamaño actual de la vista.

<ImageView 
    android:layout_width="90px" 
    android:layout_height="60px"
    android:scaleType="fitXY" />
Ian Leslie
fuente
4

La forma más simple es obtener el ancho y la altura de un ImageView en el método onWindowFocusChanged de la actividad

 @Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    height = mImageView.getHeight();
    width = mImageView.getWidth();

}
Aqib
fuente
1
onWindowFocusChanged solo funciona en API18 y más, y no puede ser la mejor manera ... sin embargo, gracias
Milad gh
1

Si ha creado varias imágenes dinámicamente, pruebe esta:

// inicializa tu matriz de imágenes

private ImageView myImages[] = new ImageView[your_array_length];

// crea programáticamente y agrega a la vista padre

 for (int i = 0; i < your_array_length; i++) {
                myImages[i] = new ImageView(this);
                myImages[i].setId(i + 1);
                myImages[i].setBackgroundResource(your_array[i]);
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                        frontWidth[i], frontHeight[i]);
                ((MarginLayoutParams) params).setMargins(frontX_axis[i],
                        frontY_axis[i], 0, 0);
                myImages[i].setAdjustViewBounds(true);
                myImages[i].setLayoutParams(params);

                if (getIntent() != null && i != your_array,length) {
                    final int j = i;
                    myImages[j].getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                        public boolean onPreDraw() {
                            myImages[j].getViewTreeObserver().removeOnPreDrawListener(this);
                    finalHeight = myImages[j].getMeasuredHeight();
                        finalWidth = myImages[j].getMeasuredWidth();
                    your_textview.setText("Height: " + finalHeight + " Width: " + finalWidth);
                            return true;
                        }
                    });
                }
                your_parent_layout.addView(myImages[i], params);
            }

// Eso es. Feliz codificación.

Hiren Patel
fuente
-2

mi amigo no está obteniendo la altura de la imagen almacenada en db. pero está obteniendo la altura de la vista. para obtener la altura de la imagen, debe crear un mapa de bits a partir de la imagen de db, y luego puede obtener la altura y el ancho de la vista de imagen

chikka.anddev
fuente
2
Sé el alto y el ancho de la imagen, pero quiero saber el alto y el ancho de ImageView para poder escalarlo en consecuencia. Espero que entiendas mi punto.
AZ_