Как я могу сделать коробку или карту похожей на мой дизайн?

Я хотел бы создать дизайн, похожий на картинку ниже.

Я просмотрел фигуру в Android Jetpack Compose, но не смог ее найти. Я не уверен, какие представления мне следует использовать для создания этого макета.

Я хочу, чтобы коробка с верхней правой стороной была круглой, как на изображении.

1
0
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Обычно для реализации таких компонентов пользовательских фигур следует использовать векторы .svg. В случае создания реактивного ранца для рисования фона за содержимым произвольной формы вам следует использовать модификатор .drawBehind, примененный к вашему содержимому, завернутому в Box. Пример кода:

val painter = rememberVectorPainter(image = vector)
Box(modifier = Modifier.drawBehind{
  with(painter) {
        draw(painter.intrinsicSize)
    }  
}) {
    your_content
}

братан, я знаю, но .SVG невозможен, поэтому я спрашиваю об этом здесь, иначе я бы использовал его.

Pradeep Rai 27.08.2024 13:19
Ответ принят как подходящий

Чтобы создать дизайн, подобный изображенному на картинке, вы можете использовать нестандартную форму. Вот как вы можете это сделать:

1. Создайте собственную фигуру:

val shape = remember {
    GenericShape { size, _ ->
        val width = size.width
        val height = size.height

        moveTo(0f, radius)
        quadraticBezierTo(0f, 0f, radius, 0f)

        lineTo(width - cornerRadius - radius, 0f)
        quadraticBezierTo(width - cornerRadius, 0f, width - cornerRadius, radius)

        quadraticBezierTo(width - 1.2f*cornerRadius, 1.2f*cornerRadius, width - radius, cornerRadius)


        quadraticBezierTo(width, cornerRadius, width, cornerRadius + radius)

        lineTo(width, height - radius)
        quadraticBezierTo(width, height, width - radius, height)

        lineTo(radius, height)
        quadraticBezierTo(0f, height, 0f, height - radius)

        lineTo(0f, radius)
    }
}

2. Примените форму к Card:

Card(
    modifier = Modifier.fillMaxSize(),
    shape = shape
) {
   content()
}

3. Добавьте циркуляр Box:

Box(
    modifier = Modifier
        .size(cornerRadiusDp - padding)
        .align(Alignment.TopEnd)
        .background(
            color = CardDefaults.cardColors().containerColor,
            shape = CircleShape
        )
)

4. Соедините Card и круговую Box вместе в родительском элементе Box:

Box(modifier = modifier) {
    Card(
        modifier = Modifier.fillMaxSize(),
        shape = shape
    ) {
        content()
    }

    Box(
        modifier = Modifier
            .size(cornerRadiusDp - padding)
            .align(Alignment.TopEnd)
            .background(
                color = CardDefaults.cardColors().containerColor,
                shape = CircleShape
            )
    )
}

Вот полный пример:


import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.GenericShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            Box(
                modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                CustomCard(modifier = Modifier
                    .width(300.dp)
                    .height(250.dp)
                ) {

                    val price = buildAnnotatedString {
                        withStyle(SpanStyle(color = Color.Green)) { append("$") }
                        append("0.00")
                    }

                    val labelStyle = remember {
                        TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Light)
                    }

                    val priceStyle = remember {
                        TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
                    }

                    Column(
                        modifier = Modifier.padding(16.dp)
                    ) {

                        Text(text = "Today", style = labelStyle)
                        Text(text = price, style = priceStyle)

                        Spacer(modifier = Modifier.weight(1f))

                        Text(text = "Yesterday", style = labelStyle)
                        Text(text = price, style = priceStyle)

                        Spacer(modifier = Modifier.weight(1f))

                        Text(text = "Past Week", style = labelStyle)
                        Text(text = price, style = priceStyle)
                    }
                }
            }
        }
    }
}

@Composable
fun CustomCard(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    val radius = with(LocalDensity.current) { 10.dp.toPx() }

    val cornerRadiusDp = 50.dp
    val cornerRadius = with(LocalDensity.current) { cornerRadiusDp.toPx() }

    val padding = 5.dp

    // Create a custom shape
    val shape = remember {
        GenericShape { size, _ ->
            val width = size.width
            val height = size.height

            moveTo(0f, radius)
            quadraticBezierTo(0f, 0f, radius, 0f)
            lineTo(width - cornerRadius - radius, 0f)
            quadraticBezierTo(width - cornerRadius, 0f, width - cornerRadius, radius)

            quadraticBezierTo(width - 1.2f*cornerRadius, 1.2f*cornerRadius, width - radius, cornerRadius)
            
            quadraticBezierTo(width, cornerRadius, width, cornerRadius + radius)

            lineTo(width, height - radius)
            quadraticBezierTo(width, height, width - radius, height)

            lineTo(radius, height)
            quadraticBezierTo(0f, height, 0f, height - radius)

            lineTo(0f, radius)
        }
    }

    Box(modifier = modifier) {
        Card(
            modifier = Modifier.fillMaxSize(),
            shape = shape
        ) {
            content()
        }

        Box(
            modifier = Modifier
                .size(cornerRadiusDp - padding)
                .align(Alignment.TopEnd)
                .background(
                    color = CardDefaults.cardColors().containerColor,
                    shape = CircleShape
                )
        )
    }
}

Демо:

Другой пример см. в этом ответе.

спасибо, братан. Он работает идеально. <3

Pradeep Rai 29.08.2024 08:02

Вы можете изучить использование Canvas и его функций, например drawAct()drawOval() и т. д. Проверьте документ в Google: https://developer.android.com/develop/ui/compose/graphics/draw/overview

Другие вопросы по теме