Это не самое эффективное решение, но, как кто-то предложил вместо фона, вы можете создать FrameLayout или RelativeLayout и использовать ImageView в качестве псевдо-фона - другие элементы будут располагаться просто над ним:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="@+id/ivBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="fitStart"
android:src="@drawable/menu_icon_exit" />
<Button
android:id="@+id/bSomeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="61dp"
android:layout_marginTop="122dp"
android:text="Button" />
</RelativeLayout>
Проблема с ImageView заключается в том, что доступны только масштабированные типы:
CENTER, CENTER_CROP, CENTER_INSIDE, FIT_CENTER, FIT_END, FIT_START, FIT_XY, MATRIX
(http://etcodehome.blogspot.de/2011/05/android-imageview-scaletype-samples.html)
и для «масштабирования фонового изображения (с сохранением его соотношения сторон)» в некоторых случаях, когда требуется, чтобы изображение заполняло весь экран (например, фоновое изображение) и соотношение сторон экрана отличалось от изображения, необходимое scaleType является разновидностью TOP_CROP, потому что:
CENTER_CROP центрирует масштабированное изображение вместо выравнивания верхнего края с верхним краем просмотра изображения, а FIT_START соответствует высоте экрана и не заполняет ширину. И, как заметил пользователь Anke, FIT_XY не сохраняет соотношение сторон.
Рад, что кто-то расширил ImageView для поддержки TOP_CROP
public class ImageViewScaleTypeTopCrop extends ImageView {
public ImageViewScaleTypeTopCrop(Context context) {
super(context);
setup();
}
public ImageViewScaleTypeTopCrop(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public ImageViewScaleTypeTopCrop(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
private void setup() {
setScaleType(ScaleType.MATRIX);
}
@Override
protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {
float frameWidth = frameRight - frameLeft;
float frameHeight = frameBottom - frameTop;
if (getDrawable() != null) {
Matrix matrix = getImageMatrix();
float scaleFactor, scaleFactorWidth, scaleFactorHeight;
scaleFactorWidth = (float) frameWidth / (float) getDrawable().getIntrinsicWidth();
scaleFactorHeight = (float) frameHeight / (float) getDrawable().getIntrinsicHeight();
if (scaleFactorHeight > scaleFactorWidth) {
scaleFactor = scaleFactorHeight;
} else {
scaleFactor = scaleFactorWidth;
}
matrix.setScale(scaleFactor, scaleFactor, 0, 0);
setImageMatrix(matrix);
}
return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);
}
}
https://stackoverflow.com/a/14815588/2075875
Теперь ИМХО было бы идеально, если бы кто-нибудь написал собственный Drawable, который масштабирует изображение таким образом. Затем его можно использовать в качестве параметра фона.
Reflog предлагает предварительно масштабировать отрисовку перед ее использованием. Вот инструкция, как это сделать:
Java (Android): как масштабировать чертеж без растрового изображения?
Хотя он имеет недостаток, этот масштабируемый чертеж / растровое изображение будет использовать больше оперативной памяти, в то время как масштабирование на лету, используемое ImageView, не требует больше памяти. Преимущество может быть меньше загрузки процессора.