Я пытаюсь установить фотографию в качестве фона Activity
. Я хочу, чтобы фон был полноэкранным изображением (без границ).
Как бы я хотел, чтобы изображение заполняло весь фон активности без растягивания/сжатия (т.е. непропорциональное масштабирование для X и Y), и я не возражаю, если фотография должна быть обрезана, я использую RelativeLayout
с a ImageView
(с android:scaleType="centerCrop"
), а остальная часть моего макета состоит из ScrollView
и его дочерних элементов.
<!-- Tried this with a FrameLayout as well... -->
<RelativeLayout>
<!-- Background -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<!-- Form -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView>
<LinearLayout>
...
<EditText/>
</LinearLayout>
</ScrollView>
</LinearLayout>
</RelativeLayout>
Проблема в том, что в остальной части макета есть несколько представлений EditText
, и когда появляется экранная клавиатура, ImageView получает размер. Я хотел бы, чтобы фон оставался прежним, независимо от того, видна ли панель клавиатуры или нет.
Я видел множество вопросов относительно SO о том, что ImageViews повторно размер, но (imo) нет удовлетворительных ответов. Большинство из них состоят только в установке android:windowSoftInputMode="adjustPan"
, что не всегда практично, особенно если вы хотите, чтобы пользователь мог прокручивать в своей деятельности - или используя getWindow().setBackgroundDrawable()
, который не обрезает изображение.
Мне удалось подкласса ImageView и переопределить его onMeasure()
(см. мой ответ здесь: ImageView изменяет размер при открытии клавиатуры), чтобы он мог заставить фиксированная высота и ширина - равные размеру экрана устройства - в соответствии с флагом, но мне интересно, есть ли лучший способ достичь желаемого результата.
Итак, чтобы подвести итог, мой вопрос: Как установить фоном активности в полноэкранную фотографию
-
с типом масштаба = "centerCrop", так что фотография масштабируется равномерно (поддерживая ее соотношение сторон), и поэтому обе размеры (ширина и высота) будут равны или больше соответствующего размера представления;
-
, который не изменяется при появлении экранной клавиатуры;
ОТВЕТ:
Я закончил следующий @pskink совет и подклассифицировал BitmapDrawable
(см. его ответ ниже). Я должен был сделать некоторые настройки, чтобы убедиться, что BackgroundBitmapDrawable
всегда масштабируется и обрезается таким образом, который заполняет экран.
Вот мой последний класс, адаптированный из его ответа:
public class BackgroundBitmapDrawable extends BitmapDrawable {
private Matrix mMatrix = new Matrix();
private int moldHeight;
boolean simpleMapping = false;
public BackgroundBitmapDrawable(Resources res, Bitmap bitmap) {
super(res, bitmap);
}
@Override
protected void onBoundsChange(Rect bounds) {
if (bounds.height() > moldHeight) {
moldHeight = bounds.height();
Bitmap b = getBitmap();
RectF src = new RectF(0, 0, b.getWidth(), b.getHeight());
RectF dst;
if (simpleMapping) {
dst = new RectF(bounds);
mMatrix.setRectToRect(src, dst, ScaleToFit.CENTER);
} else {
// Full Screen Image -> Always scale and center-crop in order to fill the screen
float dwidth = src.width();
float dheight = src.height();
float vwidth = bounds.width();
float vheight = bounds.height();
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
mMatrix.setScale(scale, scale);
mMatrix.postTranslate(dx, dy);
}
}
}
@Override
public void draw(Canvas canvas) {
canvas.drawColor(0xaa00ff00);
canvas.drawBitmap(getBitmap(), mMatrix, null);
}
}
Тогда это просто вопрос создания BackgroundBitmapDrawable
и установки его в качестве корня View background.