Как сделать так, чтобы составной текст занимал x% ширины строки, когда в строке есть IconButton?

У меня есть строка, в которой слева есть кнопка со значком, затем отступ 16 dp, затем текст, который занимает оставшуюся ширину строки, и, наконец, справа еще один текст, который должен занимать 25 % ширины строки. . Все работает, за исключением того, что второй текст фактически занимает 25% ширины строки, не считая ширины кнопки со значком. Это делает ширину второго текста слишком тонкой.

Мне нужно, чтобы второй текст составлял ровно 25% ширины всей строки, потому что у меня есть другие строки с текстами (не показаны), которые необходимо выровнять с этой.

Итак, как мне сделать так, чтобы ширина IconButton действительно учитывалась в ширине второго текста? Вот упрощенный фрагмент:

Row(
    modifier = Modifier
        .padding(bottom = 16.dp)
        .fillMaxWidth()
        .background( color = Color(50, 50, 50) )
) {
    IconButton(
        modifier = Modifier
            .background(Color(100, 100, 100), CircleShape),
        onClick = { /* nothing */ }
    ) {
        Icon(Icons.Filled.Star,null, tint = Color(255, 192,0))
    }

    Text(
        modifier = Modifier
            .weight(1f) // Use weight 1f to take up remaining space
            .padding(start = 16.dp) // put left padding on the text: between the icon button & the text
            .background(color = Color(100, 100, 100)),
        text = "Remaining space",
        style = MaterialTheme.typography.bodyMedium
    )

    Text(
        text = "25%",
        modifier = Modifier
            .fillMaxWidth(0.25f) // Take up exactly 25% of the width
            .background(color = Color(150, 150, 150)),
        textAlign = TextAlign.Center,
        style = MaterialTheme.typography.bodyMedium
    )
}

Вот (обрезанный) скриншот вывода:

И скриншот, который доказывает, что второй текст занимает только 25% ширины строки, исключая ширину IconButton (похоже, что ширина второго текста * 4 перекрывает IconButton на пару пикселей, но в моем коде, прежде чем я его упростил, дублирования не было, поэтому не думаю, что это актуально):

Изначально кнопка-иконка была в отдельной функции, поэтому я извлек ее из функции. Я также попробовал установить modifier.size() кнопки со значком вместо того, чтобы просто использовать размер по умолчанию. И то, и другое не имело никакого эффекта.

Ожидаемый результат: второй текст занимает ровно 25% ширины кнопки со значком + отступ + первый текст + второй текст.

Фактический результат: второй текст занимает ровно 25% ширины отступа + первый текст + второй текст.

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

Ответы 1

Ответ принят как подходящий

Вы можете обернуть IconButton и первый текст в дополнительную строку, где вы явно установите ширину 75%:

Row(
    modifier = Modifier.fillMaxWidth(0.75f),
) {
    IconButton()

    Text(
        modifier = Modifier.weight(1f) // Use weight 1f to take up the remaining space
    )
}

Text(
    modifier = Modifier.fillMaxWidth() // Take up the remaining 25% of the parent's width
)

Тогда второй Текст может занять оставшиеся 25%:

Я не голосовал против, но можете ли вы объяснить, почему подход ОП не сработал? Разве это не работает, потому что Compose просто измеряет дочерние элементы Row один за другим, и, таким образом, как только он достигает fillMaxWidth(0.25f), уже «слишком поздно»?

BenjyTec 08.07.2024 08:30

Да, в принципе это верно. width(1f) первого текста позволяет остальным элементам (без width) сначала решить, насколько большими они хотят быть, только тогда они займут все оставшееся пространство. Сначала измеряется IconButton, который занимает ровно столько места, сколько необходимо. Тогда второй текст fillMaxWidth(0.25f) забирает 25% того, что осталось. Это 25% всей ширины за вычетом IconButton, как показано на снимке экрана.

Leviathan 08.07.2024 09:15

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