Как реализовать масштабируемый орнамент с сохранением пропорций в CardView
Что проверяют
Умеете ли вы выбрать формат графики и способ масштабирования, а не просто растянуть картинку на карточку. Следом спрашивают, что будет на планшете и в альбомной ориентации и как орнамент ляжет под скруглённые углы.
Как отвечать
Сначала уточните, что значит «масштабируемый»: орнамент растягивается пропорционально целиком или повторяется узором по ширине. От этого зависит решение.
- формат: для простого узора
VectorDrawable, он масштабируется без потери качества и не требует набораdrawable-xxhdpi. Документация Android советует держать векторы примерно до 200×200 dp: сложный большой рисунок дорого отрисовывать, его лучше отдать растровым WebP в нескольких плотностях; - пропорции:
ImageViewсadjustViewBounds="true"иscaleType="fitCenter"вписывает орнамент целиком,centerCropзаполняет карточку с обрезкой краёв, аfitXYпропорции ломает; - заданное соотношение сторон: внутри карточки
ConstraintLayout, у картинкиlayout_width="0dp",layout_height="0dp"иapp:layout_constraintDimensionRatio="16:9", тогда высота считается от ширины на любом экране; - повторяющийся узор: XML
<bitmap>сandroid:tileMode="repeat"в качестве фона, растр при этом не масштабируется, а повторяется; - углы: вместо старого
androidx.cardviewберитеMaterialCardView, а для скругления самой картинкиShapeableImageViewсshapeAppearance.
В Compose задача короче: Card с Image(painterResource(...), contentScale = ContentScale.Crop) и Modifier.aspectRatio(16f / 9f). Орнамент по краям можно рисовать прямо в Modifier.drawBehind, масштабируя путь под размер карточки.
Проверьте результат на разных размерах через @Preview с несколькими устройствами или в Layout Inspector.
Где спотыкаются
Ставят растровую картинку одного разрешения и fitXY. На широком экране узор сплющивается, а на плотном дисплее мылится.
Задают картинке wrap_content по высоте без adjustViewBounds. Высота берётся из исходного размера файла, и под картинкой остаются пустые полосы.
Путают 9-patch с пропорциональным масштабированием. Он растягивает заданные полосы, а не весь рисунок, и орнамент в них искажается.