Как найти ширину/высоту ImageView?

Мой вопрос похож на этот вопрос. Я использовал этот код, чтобы расширить ImageView для формирования TouchImageView . В моем методе onCreate() я хочу вызвать

setImage(Bitmap bm, int displayWidth, int displayHeight)

но я не знаю, какую ширину или высоту использовать. Когда я вызываю getHeight(), он дает мне ноль.

Я пытался избежать 0, используя ответ kcoppock на упомянутый ранее вопрос, но безуспешно. Слушатель onPreDraw() вызывается несколько раз в секунду, и я не могу понять, как вызвать его только один раз.


person GregNash    schedule 05.07.2011    source источник


Ответы (2)


Это хрупкий подход для чего-то вроде этого. Представления Android измеряются их родительским представлением с использованием метода onMeasure. Предоставляя начальный размер методу setImage для масштабирования (и особенно если вы устанавливаете его на основе размера экрана), вы вызываете сложность всякий раз, когда хотите вложить это представление в другие. Устройства с большим экраном, такие как планшеты, являются хорошим примером этого.

Более идиоматический подход реализует метод setImage TouchImageView вообще без параметров ширины/высоты. Вместо этого он отложил бы настройку масштаба и матриц до измерения и реализовал бы onMeasure что-то вроде этого:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (mNeedsInitialScale) { // Set by setImage when a new image is set
        // The measured width and height were set by super.onMeasure above
        setInitialScale(getMeasuredWidth(), getMeasuredHeight());
        mNeedsInitialScale = false;
    }
}

Где метод setInitialScale делает все, что делает связанный метод setImage после вызова super.setImageBitmap. setImage следует также установить в поле mNeedsInitialScale значение true.

Таким образом, вам никогда не придется беспокоиться об используемом начальном размере, он будет автоматически получен из представления во время обычного измерения всякий раз, когда устанавливается новое изображение.

person adamp    schedule 06.07.2011
comment
Спасибо за Ваш ответ. Это решило мою проблему, и теперь мой код стал намного лучше. - person GregNash; 08.07.2011
comment
На самом деле, похоже, все работает хорошо, но getMeasuredWidth() и getMeasuredHeight() похоже возвращают ширину и высоту родительского представления. - person GregNash; 08.07.2011
comment
Оказывается, onMeasure(int int) вызывается несколько раз для измерения ImageView. Я ожидаю, что он будет вызываться всякий раз, когда добавляется родной брат. Я переместил mNeedsInitialScale = false; в начало моего метода setScale(float), и теперь он работает нормально. - person GregNash; 08.07.2011
comment
Да, onMeasure будет вызываться всякий раз, когда представлению будет предложено измерить с другими MeasureSpecs, чем в прошлый раз. Это может произойти всякий раз, когда запрашивается макет. Рад, что это сработало. :) - person adamp; 09.07.2011

размеры ImageViews равны 0, пока ваша активность не нарисует их на экране. Вы можете использовать Activity onFocusChanged, чтобы установить растровое изображение и получить правильные размеры, если вы просто ищете DisplayWidth и высоту, которую вы можете вызвать

Display d = getSystemService(WINDOW_SERVICE).getDefaultDisplay();

и спросите Display о его размерах

person Rafael T    schedule 05.07.2011