如何在 Row jetpack compose 中在末尾对齐视图

Viv*_*odi 2 android kotlin android-jetpack android-jetpack-compose

我想在屏幕末尾显示视图。像这样的东西

预期输出

在此输入图像描述

我尝试了一些代码,但它无法正常工作

@Preview(showBackground = true)
@Composable
fun Xyz(
    title: String = "Hello world",
    subTitle: String = "How are you?",
    showImage: Boolean = true
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(Icons.Rounded.ShoppingCart, contentDescription = null)
        Column(Modifier.padding(start = dimensionResource(R.dimen.home_progress_test_in_progress_padding))) {
            AnimatedVisibility(visible = title.isNotEmpty()) {
                Text(text = title, maxLines = 1, overflow = TextOverflow.Ellipsis)
            }
            AnimatedVisibility(visible = subTitle.isNotEmpty()) {
                Text(text = subTitle, maxLines = 1, overflow = TextOverflow.Ellipsis)
            }
        }
        AnimatedVisibility(visible = showImage) {
            Image(
                Icons.Rounded.AccountBox,
                contentDescription = null
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

实际产量

在此输入图像描述

我试图在这个答案Modifier.align(End)的帮助下添加,但它给了我错误

    AnimatedVisibility(
        modifier = Modifier.align(End),
        visible = showImage
    ) {
        Image(
            Icons.Rounded.AccountBox,
            contentDescription = null
        )
    }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Thr*_*ian 7

您可以使用Spacerwith Modifier.weight(1f)inside Row。里面找不到Modifier.align那是很正常的。链接调用中的答案Alignment.HorizontalRowScopeModifier.alignColumnScope

@Preview(showBackground = true)
@Composable
fun Xyz(
    title: String = "Hello world",
    subTitle: String = "How are you?",
    showImage: Boolean = true
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .border(1.dp, Color.Red),
        verticalAlignment = Alignment.CenterVertically
    ) {

        Icon(Icons.Rounded.ShoppingCart, contentDescription = null)
        Column(Modifier.padding(start = 16.dp)) {
            AnimatedVisibility(visible = title.isNotEmpty()) {
                Text(text = title, maxLines = 1, overflow = TextOverflow.Ellipsis)
            }
            AnimatedVisibility(visible = subTitle.isNotEmpty()) {
                Text(text = subTitle, maxLines = 1, overflow = TextOverflow.Ellipsis)
            }
        }

        
        Spacer(modifier = Modifier.weight(1f))
        
        AnimatedVisibility(
            visible = showImage
        ) {
            Image(
                Icons.Rounded.AccountBox,
                contentDescription = null
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

RowScopea 中可用的Row定义为

@LayoutScopeMarker
@Immutable
@JvmDefaultWithCompatibility
interface RowScope {
    /**
     * Size the element's width proportional to its [weight] relative to other weighted sibling
     * elements in the [Row]. The parent will divide the horizontal space remaining after measuring
     * unweighted child elements and distribute it according to this weight.
     * When [fill] is true, the element will be forced to occupy the whole width allocated to it.
     * Otherwise, the element is allowed to be smaller - this will result in [Row] being smaller,
     * as the unused allocated width will not be redistributed to other siblings.
     *
     * @param weight The proportional width to give to this element, as related to the total of
     * all weighted siblings. Must be positive.
     * @param fill When `true`, the element will occupy the whole width allocated.
     */
    @Stable
    fun Modifier.weight(
        /*@FloatRange(from = 0.0, fromInclusive = false)*/
        weight: Float,
        fill: Boolean = true
    ): Modifier

    /**
     * Align the element vertically within the [Row]. This alignment will have priority over the
     * [Row]'s `verticalAlignment` parameter.
     *
     * Example usage:
     * @sample androidx.compose.foundation.layout.samples.SimpleAlignInRow
     */
    @Stable
    fun Modifier.align(alignment: Alignment.Vertical): Modifier

    /**
     * Position the element vertically such that its [alignmentLine] aligns with sibling elements
     * also configured to [alignBy]. [alignBy] is a form of [align],
     * so both modifiers will not work together if specified for the same layout.
     * [alignBy] can be used to align two layouts by baseline inside a [Row],
     * using `alignBy(FirstBaseline)`.
     * Within a [Row], all components with [alignBy] will align vertically using
     * the specified [HorizontalAlignmentLine]s or values provided using the other
     * [alignBy] overload, forming a sibling group.
     * At least one element of the sibling group will be placed as it had [Alignment.Top] align
     * in [Row], and the alignment of the other siblings will be then determined such that
     * the alignment lines coincide. Note that if only one element in a [Row] has the
     * [alignBy] modifier specified the element will be positioned
     * as if it had [Alignment.Top] align.
     *
     * @see alignByBaseline
     *
     * Example usage:
     * @sample androidx.compose.foundation.layout.samples.SimpleAlignByInRow
     */
    @Stable
    fun Modifier.alignBy(alignmentLine: HorizontalAlignmentLine): Modifier

    /**
     * Position the element vertically such that its first baseline aligns with sibling elements
     * also configured to [alignByBaseline] or [alignBy]. This modifier is a form
     * of [align], so both modifiers will not work together if specified for the same layout.
     * [alignByBaseline] is a particular case of [alignBy]. See [alignBy] for
     * more details.
     *
     * @see alignBy
     *
     * Example usage:
     * @sample androidx.compose.foundation.layout.samples.SimpleAlignByInRow
     */
    @Stable
    fun Modifier.alignByBaseline(): Modifier

    /**
     * Position the element vertically such that the alignment line for the content as
     * determined by [alignmentLineBlock] aligns with sibling elements also configured to
     * [alignBy]. [alignBy] is a form of [align], so both modifiers
     * will not work together if specified for the same layout.
     * Within a [Row], all components with [alignBy] will align vertically using
     * the specified [HorizontalAlignmentLine]s or values obtained from [alignmentLineBlock],
     * forming a sibling group.
     * At least one element of the sibling group will be placed as it had [Alignment.Top] align
     * in [Row], and the alignment of the other siblings will be then determined such that
     * the alignment lines coincide. Note that if only one element in a [Row] has the
     * [alignBy] modifier specified the element will be positioned
     * as if it had [Alignment.Top] align.
     *
     * Example usage:
     * @sample androidx.compose.foundation.layout.samples.SimpleAlignByInRow
     */
    @Stable
    fun Modifier.alignBy(alignmentLineBlock: (Measured) -> Int): Modifier
}
Run Code Online (Sandbox Code Playgroud)