ImageView не масштабируется на устройствах с большим экраном

Вот мой основной макет:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ImageView android:adjustViewBounds="true" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/welcome_hero" /> </LinearLayout> 

Я хочу, чтобы изображение масштабировалось, сохраняя соотношение сторон, чтобы оно соответствовало экрану.

Это прекрасно работает на устройствах mdpi (LG LGP509) и hdpi (HTC G2, Nexus One). Однако на моем Galaxy Nexus (xhdpi) изображение упрямо не масштабируется, чтобы соответствовать. Он оставляет дополнительное пространство по бокам.

Вот еще информация:

  • Макет находится в общей папке / папке

  • Welcome_hero.png находится в папке drawables / и имеет ширину 320 пикселей и высоту 161 пиксель

В AndroidManifest.xml есть эта запись:

 <uses-sdk android:targetSdkVersion="10" android:minSdkVersion="8" /> <supports-screens android:xlargeScreens="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="false" /> 

Некоторые вещи, которые я пробовал:

  • Изменение scaleType в fitCenter, fitInside или матрицу дали те же результаты, что и без
  • Изменяя высоту ImageView, чтобы fill_parent правильно масштабировал изображение, но нажал все остальные виды с экрана
  • Угрожающий монитор физическим насилием оставил меня более расстроенным
  • Явно задал высоту и ширину 320dp и 161dp ничего не изменил
  • Как уже упоминалось выше, я пробовал новые макеты как в предварительном просмотре IntelliJ, так и на физических устройствах

Я прохожу через StackOverflow около 1,5 часов, глядя на сотни сообщений, которые похожи на мои, но, похоже, никто не работает над Galaxy Nexus. Я отчаянно пытаюсь стать хорошим разработчиком и сделать свой материал на новых телефонах, но это сложно.

Используйте комбинацию разметки и кода макета для масштабирования:

Сохраните свой layout_width = "fill_parent" и layout_height = "wrap_content". Добавить

 android:scaleType="fitXY" 

В вашем коде:

 ImageView mImageView = findViewById (R.id.yourimageid); LayoutParams lp = mImageView.getLayoutParams(); lp.height = (int)((float)context.getWindowManager().getDefaultDisplay().getWidth() * ((float)mImageView.getDrawable().getIntrinsicHeight() / (float)mImageView.getDrawable().getIntrinsicWidth())); mImageView.setLayoutParams(lp); 

Т.е. вы устанавливаете новое значение для layout_height, умножая ширину экрана * отношение высоты изображения к ширине.

Вероятно, вы хотите установить android:adjustViewBounds – true. Сохраняйте свою ширину fill_parent и height wrap_content . Вам все равно придется играть с вашим scaleType чтобы он работал, как ожидалось, хотя масштабирование имеет тенденцию быть сложным с использованием этого подхода.

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

 public class AspectRatioImageView extends ImageView { private final boolean horizontal; public AspectRatioImageView(Context context) { this(context, null); } public AspectRatioImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AspectRatioImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AspectRatioImageView, defStyle, 0); int h = array .getInt(R.styleable.AspectRatioImageView_fixedDimension, 0); horizontal = (h == 0); array.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { boolean widthExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; boolean heightExactly = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY; float ratio; try { ratio = ((float) ((BitmapDrawable) getDrawable()) .getIntrinsicWidth()) / ((float) ((BitmapDrawable) getDrawable()) .getIntrinsicHeight()); } catch (ClassCastException e) { ratio = MeasureSpec.getSize(widthMeasureSpec) / MeasureSpec.getSize(heightMeasureSpec); } int heightRatioSpec = MeasureSpec.makeMeasureSpec( (int) (MeasureSpec.getSize(widthMeasureSpec) / ratio), MeasureSpec.EXACTLY); int widthRatioSpec = MeasureSpec.makeMeasureSpec( (int) (MeasureSpec.getSize(heightMeasureSpec) * ratio), MeasureSpec.EXACTLY); if (widthExactly) { if (heightExactly) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } else { super.onMeasure(widthMeasureSpec, heightRatioSpec); } } else { if (heightExactly) { super.onMeasure(widthRatioSpec, heightMeasureSpec); } else { if (horizontal) { super.onMeasure(widthMeasureSpec, heightRatioSpec); } else { super.onMeasure(widthRatioSpec, heightMeasureSpec); } } } } } 

Вам также нужно будет добавить

 <declare-styleable name="AspectRatioImageView"> <attr format="enum" name="fixedDimension"> <enum name="horizontal" value="0" /> <enum name="vertical" value="1" /> </attr> </declare-styleable> 

На ваш /values/attr.xml, чтобы вы могли использовать app:fixedDimension=horizontal чтобы он знал, чтобы масштабировать вертикальное измерение.

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

Я считаю, что установка scaleType centerInside сделает эту работу. Центрировать урожай стоит попробовать, если центр внутри не работает. См. http://developer.android.com/reference/android/widget/ImageView.ScaleType.html.

Вместо использования android:src на вашем изображенииView XML , используйте android:background . Это должно решить масштабные проблемы.

См. Здесь: В чем разница между src и фоном ImageView