Размер экрана устройства странно влияет на масштабированные изображения - PullRequest
6 голосов
/ 10 февраля 2012

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

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

<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:

с центром внутри

AVDS:

Edit:

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 14 февраля 2012

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

Вот причина, по которой он так себя ведет (из ImageView.onMeasure (int, int) [строка 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
}

То, что он делает, это регулирует высоту вида, только если новая высота, основанная на соотношении сторон рисованного объекта и отрегулированной ширине (в нашем случае это точная ширина родительского вида), равна меньше , чем скорректированная высота (которая в данном случае является просто собственной высотой рисования плюс отступ в нашем случае. Дайте мне знать, если вы хотите, чтобы я затормозил эту точку дальше.)

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

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

heightSize = resolveAdjustedSize(newHeight, mMaxHeight, heightSpec);

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

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

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

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

0 голосов
/ 14 февраля 2012

Как я понимаю, нужно масштабировать изображение, сохраняя его пропорции.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" />
...