Jak uzyskać szerokość i wysokość android.widget.ImageView?

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

Mam widok obrazu z pewną domyślną wysokością i szerokością, obrazy są przechowywane w db i chcę skalować obraz zgodnie z szerokością wysokości Imageview. Ponieważ nie chcę, aby podawał wartości domyślne, ponieważ za każdym razem, gdy zmieniam jego wysokość i szerokość, muszę go również zmieniać w kodzie.

Próbuję uzyskać wysokość i szerokość ImageView, ale w obu przypadkach zwracane jest 0.

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

zwraca mi 0, nawet jeśli ma domyślną wysokość i szerokość

AZ_
źródło
«Ponieważ nie chcę podawać wartości domyślnych, ponieważ za każdym razem, gdy zmieniam jego wysokość i szerokość, muszę to również zmienić w kodzie» - który z nich można zmienić? widok obrazu czy zapisane obrazy?
Pedro Loureiro,
nie możesz po prostu użyć android:scaleType="centerInside"?
bigstones 13.01.11
2
@nightcracker: To nie jest ASCII.
Joey,
7
@ Whenοеу Kiedy mówiłem „ASCII”, miałem na myśli „sztukę ASCII”, która obejmuje więcej sztuki niż ta, która składa się jedynie z zestawu znaków ASCII.
lub
1
To nie odpowiada bezpośrednio na pytanie, ale jeśli zastanawiasz się, dlaczego getHeight () / getWidth () zwracają 0, zawsze zwracają 0, jeśli wywołasz te metody przed „rysowaniem” widoku, tj. Jeśli wywołanie tych metod w onCreate () zwróci 0
audiojared

Odpowiedzi:

222

Moja odpowiedź na to pytanie może ci pomóc:

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;
    }
});

Następnie możesz dodać pracę skalowania obrazu z poziomu metody onPreDraw ().

Kevin Coppock
źródło
8
bardzo miły brat kod i logiczne +1 do tego. możesz to również osiągnąć, ustawiając właściwość ImageView android: adjustViewBounds = "true" na true :)
AZ_
hej, ale podczas debugowania wskaźnika nie używaj funkcji onPreDraw (). Dlaczego tak jest?
Geetanjali,
3
Myślę, że musisz dodać vto.removeOnPreDrawListener (this); linia wewnątrz onPreDraw ()
sagus_helgy
1
@ KK_07 zobacz zmianę zgodnie z komentarzem Cierpiącego. Wystarczy usunąć nasłuchiwanie po zakończeniu.
Kevin Coppock
6
jak przypisujesz wartości do finalHeight i finalWidth wewnątrz klasy wewnętrznej, nie czyniąc ich ostatecznymi?
Chris
29

Właśnie ustawiłem tę właściwość, a teraz system operacyjny Android zajmuje się wszystkim.

android: adjustViewBounds = "true"

Użyj tego w pliku layout.xml, w którym zasadziłeś ImageView: D

AZ_
źródło
4
@jww Naprawdę nie odpowiadam negatywnym wyborcom: p. Najpierw przeczytaj o getWidth i getMeasured w dokumentacji Androida. potem przychodzą i głosują ludzie.
AZ_
27

Mógłbym uzyskać szerokość i wysokość obrazu dzięki możliwości wyciągania;

int width = imgView.getDrawable().getIntrinsicWidth();
int height = imgView.getDrawable().getIntrinsicHeight();
Rashid
źródło
14

Powodami, dla których ImageView ma wartość 0, jest to, że kiedy je odpytujesz, widok nadal nie wykonał kroków układu i pomiaru. Powiedziałeś tylko widokowi, jak będzie się on „zachowywał” w układzie, ale nadal nie obliczył, gdzie umieścić każdy widok.

Jak decydujesz, jaki rozmiar ma dać widok obrazu? Czy nie możesz po prostu użyć jednej z natywnych opcji skalowania?

Pedro Loureiro
źródło
Podałem domyślną wysokość i szerokość ImageView, ale kiedy próbuję wprowadzić je do kodu, zwraca mi 0. Myślę, że najpierw muszę zawężyć ImageView. ale jak?
AZ_
Zajmuję się tym w mojej odpowiedzi. Przeczytaj jeszcze raz :) Myślę, że twój widok jest już zawyżony. Możesz to zobaczyć? jeśli możesz, to jest zawyżone.
Pedro Loureiro
13

Wpis dla wątku interfejsu użytkownika działa dla mnie.

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();

            }
});
element6
źródło
Naprawdę pomocny!
Xavi Jimenez
Źle. Zapytanie o szerokość i wysokość z interfejsu użytkownika nie gwarantuje, że te wartości są gotowe. Inflacja widoków właśnie się skończyła w twojej próbie, ale może być inaczej
rommex
6

twój plik 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"/>

twój plik Java:

ImageView imageView = (ImageView)findViewById(R.id.imageView);
     int width = imageView.getDrawable().getIntrinsicWidth();
     int   height = imageView.getDrawable().getIntrinsicHeight();
omor
źródło
5

Myślę, że możesz pozwolić, aby system operacyjny Android zajął się tym za Ciebie. Ustaw typ skali w ImageView na, fitXYa wyświetlany obraz będzie miał rozmiar dopasowany do bieżącego rozmiaru widoku.

<ImageView 
    android:layout_width="90px" 
    android:layout_height="60px"
    android:scaleType="fitXY" />
Ian Leslie
źródło
4

Najprostszym sposobem jest uzyskanie szerokości i wysokości ImageView w metodzie działania onWindowFocusChanged

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

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

}
Aqib
źródło
1
onWindowFocusChanged po prostu działa na API18 i nowszych, i nie może to być najlepszy sposób ... jednak dzięki
Milad gh
1

Jeśli utworzyłeś wiele obrazów dynamicznie, spróbuj tego:

// zainicjuj tablicę zdjęć

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

// utwórz programowo i dodaj do widoku rodzica

 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);
            }

// Otóż to. Happy Coding.

Hiren Patel
źródło
-2

mój przyjacielu przez to nie otrzymujesz wysokości obrazu przechowywanego w db. ale dostajesz wysokość widoku. dla uzyskania wysokości obrazu musisz utworzyć bitmapę z db, s image. i wtedy możesz pobrać wysokość i szerokość podglądu obrazu

chikka.anddev
źródło
2
Znam wysokość i szerokość obrazu, ale chcę znać wysokość i szerokość ImageView, aby odpowiednio go skalować. Mam nadzieję, że rozumiesz.
AZ_