2012-02-10 4 views
6

Обновление: Размеры экрана нескольких устройств - это красная селедка - проблема заключается в том, что изображение не масштабируется должным образом, чтобы заполнить экран - см. Комментарии к ответу Ивана.Размер экрана устройства имеет странный эффект при масштабировании ImageViews

У меня есть файл макета с одним изображением:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/image" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:adjustViewBounds="true" 
    android:scaleType="centerCrop" /> 

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

setContentView(R.layout.image_story); 
ImageView image = (ImageView)findViewById(R.id.image); 
image.setImageDrawable(s.image); 

Вот как он оказывается на два AVD с различными размерами экрана. Они должны быть одинаковыми (подробный вопрос внизу). Извините за большие изображения.

с scaleType = centerCrop:

с centerInside

AVDS:

Edit:

С layout_height = "fill_parent" и scaleType = "centerInside"

У меня есть 2.1 AVD со значениями по умолчанию, так что экран меньше , и это работает точно так, как ожидалось - изображение масштабируется, чтобы заполнить ширину, а высота представления завернута в масштабированную высоту.

На моем Droid Bionic с более длинным экраном, и на любом AVD с теми же размерами экрана, это не работы- изображение масштабируется, чтобы заполнить ширину, но вид заворачивают в оригинальной пре- так что верхняя и нижняя части обрезаны.

Я понятия не имею, почему соотношение сторон экрана устройства повлияет на это. Я пробовал бесчисленное сочетание параметров макета и типов шкалы, пытаясь заставить это работать на Bionic. Все работает точно так, как ожидалось, на меньшем экране, а не на большем. Если я установил высоту изображения явно в dp, он работает так, как ожидалось, но я никогда не знаю, каковы будут размеры изображения (или экрана). Какие-либо предложения?

+0

Скриншоты могут быть полезны, так как я не совсем уверен, что изображу правильную вещь. – CaseyB

+0

Добавлены скриншоты - это поможет? Меньший экран дает ожидаемые результаты в масштабировании изображения. Чем больше размер, тем меньше размер для масштабирования ImageView. –

+0

Вы уверены, что хотите layout_height = wrap_content? –

ответ

4

Это очень хороший вопрос, действительно.

Вот почему он ведет себя так (от ImageView.onMeasure(int, int) [line 661]):

// Try adjusting height to be proportional to width 
if (!done && resizeHeight) { 
    int newHeight = (int)((widthSize - pleft - pright) 
      /desiredAspect) + ptop + pbottom; 
    if (newHeight <= heightSize) { // line 661 
     heightSize = newHeight; 
    } // line 663 
} 

Что она делает это регулирует высоту зрения, только если новая высота, которая основана на пропорцию из вытяжки и (в нашем случае это точная ширина родительского вида) меньше, чем скорректированная высота (которая в этом случае является только родной высотой рисунка плюс добавка в нашем случае. Сообщите мне, если вы хотите, чтобы я сбил это точка).

То, что я не понимаю, является причиной того, что существует t он ограничивает, что новая высота должна быть меньше. Это имеет смысл только в том случае, если наш heightSize либо ТОЧНО, либо AT_MOST и установлен на верхнюю границу. В других случаях это не обязательно.

Так на самом деле вместо целого куска 661 через 663 должен был еще один вызов

heightSize = resolveAdjustedSize(newHeight, mMaxHeight, heightSpec); 

, чтобы убедиться, что мы используем только ограничение по высоте, когда оно должно быть ограничено (то есть. Мы получили ограничение AT_MOST в heightSpec и значение высоты в heightSpec меньше, чем новая высота. ТОЧНО не может произойти здесь, если мы не используем переменную ширину.)

Возможно, я что-то пропустил. Ребята, кто читает это, , пожалуйста, комментарий, если вы видите какие-либо недостатки в том, что, особенно если вы часть команды Android в Google :)

PS В качестве обходного пути, я могу предложить вам реализовать пользовательский ImageView и переопределить onMeasure (int, int), чтобы установить границы вашего точного соотношения сторон. Дайте мне знать, если вам нужна помощь по фактическому коду.

UPD Я собираюсь выписать имена, чтобы привлечь внимание смарт андроида парней в Google (я надеюсь, что ребята имеют Оповещение Google Настройку): Romain Guy, Роман Нурик, Рет Майер, пожалуйста, примите Посмотрите на это обсуждение.

+0

На самом деле, только если 'newHeight' меньше, чем' heightSize', следующая настройка имеет смысл, в противном случае (если она больше) мы бы установили ** ширину ** кодом, который несколько строк раньше. –

+0

Извините, я не понимаю. Есть раздел выше, который регулирует ширину, но он только настраивает newWidth, который не используется в куске, который я разместил, поэтому он не будет компенсировать, что newHeight будет больше, чем размер высоты. Кроме того, этот раздел фактически зависит от того, как ширина была ограничена атрибутом layout_width. Если layout_with = "fill_parent", секция регулировки ширины никогда не будет выполнена, потому что resizeWidth всегда будет false. Тем не менее, нам еще нужно настроить высоту, я не понимаю, почему только в тех случаях, когда newHeight меньше высоты. Я что-то упускаю? –

+0

[Эта часть кода] (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/widget/ImageView.java#647) делает отрегулируйте 'widthSize'. Обратите внимание, что если для параметра 'done' установлено значение true, настройка высоты не будет выполнена. –

0

Как я понимаю, вам необходимо масштабировать изображение, сохраняя его соотношение сторон. scaleType="fitCenter" должно дать вам желаемое поведение:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/image" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:adjustViewBounds="true" 
    android:scaleType="fitCenter" /> 

Если это не помогает, попробуйте добавить это в файл манифеста:

<supports-screens 
    android:resizeable="true" 
    android:smallScreens="true" 
    android:normalScreens="true" 
    android:largeScreens="true" 
    android:anyDensity="true" /> 
+0

'fitCenter' не масштабирует изображение вверх, просто отображает его в верхней части экрана с оригинальным размером (например, большой« fill_parent »и scaleType =« centerInside », но в верхней части экрана). Добавление «поддержек-экранов» в манифест не оказывает никакого эффекта. –

+0

Вы пробовали обернуть свой «ImageView» в какой-то макет ('LinearLayout', например), а затем вызывать' setContentView (..) 'для этого макета? Я бы экспериментировал с различными комбинациями макетов и параметров макета. –

+0

Да, не нашли правильную комбинацию. В противном случае я использую 'setContentView' в файле макета только с« ImageView »для тестирования, и это похоже на« LinearLayout »с одним дочерним элементом. –