Я хотел бы знать, есть ли какой-либо способ указать плагину Jetpack Compose, чтобы удалить высоту по умолчанию из компонента изображения, или единственный способ - перестроить ресурс изображения.
У меня есть это:
Image(
painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
contentDescription = "login_logo",
modifier = Modifier
.align(CenterHorizontally)
.fillMaxWidth()
Которые показывают, как это
Поскольку вы можете проверить, что изображение имеет высоту, которую я не добавляю к компоненту, поэтому должен ли я воссоздать актив или есть какой-то способ его удалить.
Заранее спасибо !
[РЕДАКТИРОВАТЬ]
В качестве предложения я пытаюсь использовать пользовательскую форму, чтобы скрыть границу изображения, чтобы реализовать решение следующим образом:
val offset = with(LocalDensity.current){
4.dp.toPx()
}
val customCircleShape = GenericShape{ size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Column(
verticalArrangement = Arrangement.Top,
modifier = Modifier
.clip(customCircleShape)
.shadow(4.dp, CircleShape)
.size(60.dp)
.background(Color.White)
) {
Image(
painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
contentDescription = "login_logo",
modifier = Modifier
.align(Alignment.CenterHorizontally)
.fillMaxWidth()
.fillMaxHeight(0.25f)
.border(BorderStroke(2.dp, Color.White), CircleShape)
.background(Color.White)
)
}
Но граница все еще отображается как первая картинка, которую я добавил.
Что мне здесь не хватает?
[РЕДАКТИРОВАТЬ]
Неважно, насколько большой круг, который должен скрывать тень, не делайте этого.
Я добавляю изображение, которое я использую в качестве ссылки.
[РЕШЕНИЕ]
Я делаю работы, делая это:
val offset = with(LocalDensity.current){
8.dp.toPx()
}
val customCircleShape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Image(
painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
contentDescription = "login_logo",
contentScale = ContentScale.FillBounds,
modifier = Modifier
.align(CenterHorizontally)
.padding(10.dp)
.background(Color.White)
.clip(customCircleShape)
.size(80.dp),
)
Рассматривали ли вы попытку создать собственный эффект тени?
modifier = Modifier
.size(100.dp)
.clip(CircleShape)
.shadow(elevation = 0.dp, shape = CircleShape)
Поскольку ваш логотип может содержаться внутри круга, вы можете сделать это несколькими способами.
1- Использование функций Path и clipPath внутри drawScope Modifier.drawWithContent.
2- Создание пользовательской формы круга меньшего размера, как в варианте 1, и применение Modifier.clip(customShape)
3- Использование BlendMode с назначением drawCircle внутри Modifier.drawWithContent.
Так как у меня нет твоего логотипа. Я создал изображение, которое рисует красный круг с некоторой тенью.
@Preview
@Composable
private fun MyImage() {
Canvas(
modifier = Modifier
.shadow(4.dp, CircleShape)
.size(60.dp)
.background(Color.White)
) {
drawCircle(color = Color.Red, radius = size.width / 2 - 5.dp.toPx())
}
}
И реализовал этот модификатор как
@Preview
@Composable
fun Test() {
Column(modifier = Modifier.fillMaxSize()) {
Text(text = "Original")
MyImage()
Spacer(modifier = Modifier.height(10.dp))
val path = remember {
androidx.compose.ui.graphics.Path()
}
val offset = with(LocalDensity.current){
4.dp.toPx()
}
val customCircleShape = GenericShape{size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Clip with Shape")
Box(modifier = Modifier.clip(customCircleShape)){
MyImage()
}
Spacer(modifier = Modifier.height(10.dp))
Text(text = "drawWithContent and clipPath")
Box(
modifier = Modifier.drawWithContent {
if (path.isEmpty) {
path.addOval(
oval = Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
clipPath(path = path, clipOp = ClipOp.Intersect) {
[email protected]()
}
}
) {
MyImage()
}
}
}
Результат
Хитрость заключается в том, чтобы создать Rect для овала, который имеет смещения в обоих направлениях.
Для образца BlendMode вы можете проверить ссылку ниже. Я вырезал изображение и Button придал ему форму прямоугольника.
Как подстричь или вырезать составной?
С изображением это как
Используется только клип с параметром пользовательской формы, но другие параметры могут быть применены либо к клипу, либо к добавлению собственной тени, как это сделал я.
@Preview
@Composable
private fun Test() {
val offset = with(LocalDensity.current) {
8.dp.toPx()
}
val customCircleShape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
addOval(
Rect(
offset = Offset(
offset, offset
),
size = Size(
width = size.width - 2 * offset,
height = size.height - 2 * offset
)
)
)
}
Column(
Modifier
.fillMaxSize()
.padding(20.dp)
) {
Text("ORIGINAL")
Image(
painter = painterResource(id = R.drawable.shell),
contentDescription = null,
contentScale = ContentScale.FillBounds,
)
Text("Clipped with Shape")
Image(
modifier = Modifier
.border(1.dp, Color.Green)
.clip(customCircleShape),
painter = painterResource(id = R.drawable.shell),
contentDescription = null,
contentScale = ContentScale.FillBounds
)
Text("With Size and attached Modifier.shadow after")
Image(
modifier = Modifier
.border(1.dp, Color.Green)
.padding(10.dp)
.shadow(6.dp, spotColor = Color.Cyan, shape = CircleShape)
.background(Color.White)
.clip(customCircleShape)
.size(80.dp),
painter = painterResource(id = R.drawable.shell),
contentDescription = null,
contentScale = ContentScale.FillBounds
)
}
}
Спасибо за полный ответ. Я попытаюсь угадать ваше предположение, но все еще показываю границу вокруг изображения. Я редактирую свой исходный вопрос, добавляя код
Значение, которое я использовал, является фиксированным значением, которое соответствует тени, которую я добавил в качестве образца. Пробовали увеличить? Вы обрезаете изображение со всех сторон настолько, насколько значение смещения
И зачем ты снова добавляешь тень?
Если возможно, не могли бы вы добавить свой ресурс изображения? Или другое похожее изображение с формой круга и высотой?
Я редактирую свой пост, добавляя изображение, и да, не имеет значения, насколько большим я делаю Круг вокруг
Оно делает. Вы должны проверить мой обновленный ответ. Я разместил только с пользовательской формой, но другие тоже работают. Вы можете скопировать пасту и попробовать.
Возможно, вы не центрируете изображение внутри столбца, это может быть так. Если он не отцентрирован, вы не сможете правильно обрезать, особенно область, нарисованная растровым изображением, меньше контейнера.
Я немного изменю ваш код. Спасибо !
Также помните, что это всего лишь пример, показывающий, что вы можете вырезать часть составного объекта или изображения. Если у вас слишком большое изображение, вы должны поместить offset внутри формы и установить что-то вроде offset = size.width*0.05f, чтобы установить радиус пользовательского круга в процентах. Это может быть лучший подход. Это означает, что вы обрезаете 5% изображения с каждой стороны вместо некоторого предопределенного значения dp.
Спасибо за ваши комментарии, и да, я уже пытался сделать это: .border(BorderStroke(2.dp, Color.White), CircleShape) .background(Color.White) и ваш код тоже, и не работает