Как заполнить оставшееся пространство в LazyColumn Jetpack Compose?

У меня есть LazyColumn, который содержит 3 элемента:

LazyColumn(
    modifier = Modifier.fillMaxSize()
) {
    item {
        Text("Some text..."}
        Text("Some text..."}
    }
    item {
        Spacer(
            modifier = Modifier.weight(1f)
        )
        Text("Copyright © Max 2024")
    }
}

Моя цель — разместить текст «Авторское право…» внизу экрана. Проблема в том, что я не могу использовать Spacer с Modifier.weight(1f). Как я могу решить эту проблему без использования Column?

не можете ли вы переместить текст («Авторское право © Max 2024») наружу?

Gaurav Roy 08.08.2024 08:01

@GauravRoy Снаружи чего? Если я поставлю его после последнего элемента, я получу @Composable invocations can only happen from the context of a @Composable function, если поставлю за его пределами, то LazyColumn вообще не работает. Так как же это решить?

Always Learner 08.08.2024 08:09

я имею в виду, за пределами lazyColumn, извините, не сообщил об этом раньше

Gaurav Roy 08.08.2024 08:19

@GauravRoy Как я уже упоминал ранее, если я помещу его за пределы LazyColumn, это вообще не сработает.

Always Learner 08.08.2024 08:21

@AlwaysLearner Надеюсь, вы составляете каждое представление в разных item означает, что у вас будет более двух элементов, верно? Если это не так, это означает, что у вас будет только два элемента, как показано в коде, тогда вы можете просто использовать verticalArrangement = Arrangement.SpaceBetween вместо LazyColumn.

Atul Sharma 08.08.2024 08:29

@AtulSharma Можете показать мне пример? Все, что мне нужно, это иметь текст и текст, который будет размещен внизу экрана.

Always Learner 08.08.2024 08:32

@AlwaysLearner Мой вопрос: «В LazyColumn всегда только два предмета или больше двух?»

Atul Sharma 08.08.2024 08:38

@AtulSharma Есть два предмета + один последний предмет.

Always Learner 08.08.2024 08:41

@AlwaysLearner Теперь я понимаю, но согласно вашему примеру кода есть только два элемента, в которых любой компонуемый элемент item {} лямбда рассматривается как один элемент только для LazyLayouts, независимо от того, сколько компонуемых элементов находится внутри одного item, и когда вы используете items, он будет составлять каждый товар отдельно. Теперь по вашему желанию в вашем LazyColumn может быть любое количество предметов.

Atul Sharma 08.08.2024 08:48

@AtulSharma Так как же это решить?

Always Learner 08.08.2024 08:50

Вы можете обратиться к моему ответу о создании пользовательского Arrangment, который помещает последний элемент вниз независимо от количества элементов.

Thracian 08.08.2024 09:19

@AlwaysLearner На самом деле ваш вопрос не совсем таков, что вам следует отредактировать его должным образом, объяснив все случаи. Если вы хотите, чтобы текст авторских прав всегда присутствовал на экране, то я не понимаю, в чем проблема с использованием column. И если вы хотите, чтобы текст об авторских правах также можно было прокручивать вместе с другими элементами, если они большие по количеству и если элементов всего несколько, тогда текст об авторских правах должен быть внизу, заполняя пустое пространство. В этом случае вы также можете обратиться к stackoverflow.com/a/77350789/14972910. Это может помочь вам решить вашу задачу.

Atul Sharma 08.08.2024 09:40
0
12
67
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

вы всегда можете переместить Текст («Авторские права © Max 2024»), «Снаружи»

Column(Modifier.fillMaxSize()) {
        LazyColumn(
            modifier = Modifier.weight(1f)
        ) {
            item {
                Text("Some text...")
                Text("Some text...")
            }
        }

        Text("Copyright © Max 2024")
    }
   

Как я уже упоминал в комментарии, если я поставлю его за пределы LazyColum, это вообще не сработает.

Always Learner 08.08.2024 08:23

@AlwaysLearner, не могли бы вы предоставить родительский элемент lazycolumn, чтобы мы могли правильно ответить?

Yohanes 08.08.2024 08:25

Родителем LazyColum является Surface.

Always Learner 08.08.2024 08:31
скриншот вы можете увидеть ссылку на изображение, которую я вам показываю, она должна работать правильно @AlwaysLearner
Yohanes 08.08.2024 08:36

Я упомянул в своем вопросе, How can I solve this problem without using a Column?. Я использую LazyColumn. В любом случае спасибо.

Always Learner 08.08.2024 08:40

Так что я вижу проблему, но если вы хотите добиться максимальной производительности. LazyColumn — это не волшебный способ все оптимизировать. это похоже на то, что каждый пользовательский интерфейс — это recyclerview, который требует чрезмерного проектирования и хаоса. По моему опыту, компоновка не так уж сложна, даже если вы поместите Column внутри LazyColumn. Наиболее важным для производительности является то, как вы управляете состоянием. Но если вы все еще хотите бросить вызов себе, чтобы добиться этого, вы всегда можете попытаться получить высоту экрана и вычислить заполненный пользовательский интерфейс до нижнего текста, который я не знаю, как его закодировать.

Yohanes 08.08.2024 08:53

ОБНОВЛЯТЬ:

 val screenHeight = LocalConfiguration.current.screenHeightDp


Surface(Modifier.fillMaxSize()) {
    LazyColumn(
        modifier = Modifier.fillMaxSize(1f)
    ) {
        item {
            Text("Some text...")
            Text("Some text...")
        }
    }

    Text("Copyright © Max 2024", modifier = Modifier.offset(y = screenHeight.dp-90.dp))
}

так что мы можем использовать offest, если хотите, внизу. Примечание. Сейчас у меня есть нижняя вкладка, поэтому я добавил -90.dp, попробуйте без нее. должно работать @AlwaysLearner

Пожалуйста, опубликуйте всю структуру пользовательского интерфейса.

Я упомянул в своем вопросе, How can I solve this problem without using a Column?. Я использую LazyColumn. В любом случае спасибо.

Always Learner 08.08.2024 08:40

@AlwaysLearner, я обновил его

Gaurav Roy 08.08.2024 08:47

А как насчет того, когда экран выше? Будет ли также применяться -90.dp?

Always Learner 08.08.2024 08:51

что ты подразумеваешь под словом выше? попробуйте без -90 dp, если это работает, в противном случае отрегулируйте + или - некоторое dp

Gaurav Roy 08.08.2024 08:52

круто, рад, что помогло. примите это как правильное, если считаете это правильным

Gaurav Roy 08.08.2024 09:06
Ответ принят как подходящий

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

Результат

Код

val ArrangementLazyColumnLastItemToBottom = object : Arrangement.Vertical {
    override fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray) {
        var consumedHeight = 0
        sizes.forEachIndexed { index, height ->
            if (index == sizes.lastIndex) {
                // If it's last item position at the bottom
                outPositions[index] = totalSize - height
            } else {
                // If not last item position below other
                outPositions[index] = consumedHeight
                consumedHeight += height
            }
        }
    }
}

@Preview
@Composable
fun LazyColumnArrangmentTest() {

    LazyColumn(
        modifier = Modifier.fillMaxSize().border(2.dp, Color.Red),
        verticalArrangement = ArrangementLazyColumnLastItemToBottom
    ) {
        item {
            Text("Text1")
        }
        item {
            Text("Text2")
        }

        item {
            Text("Text3")
        }

        item {
            Text("Text4")
        }
        item {
            Text("Text5")
        }

        item {
            Text("Footer")
        }
    }
}

Позвольте мне попытаться вернуться к вам. Спасибо за ответ.

Always Learner 08.08.2024 09:47

В этом решении текст нижнего колонтитула помещается в центр оставшегося пустого пространства. Но это решение stackoverflow.com/a/77350789/14972910 может оказаться внизу пустого пространства.

Atul Sharma 08.08.2024 09:49

Я проверил это, и это не ставит его в центр пустого пространства. Это помещает нижнюю часть доступного пространства, потому что outPositions[index] = totalSize - consumedHeight. TotalSize — это нижняя часть Composable, которая использует это расположение.

Thracian 08.08.2024 09:51

Должно быть -height Hard, а не ConsumerHeight.

Thracian 08.08.2024 09:59

@Thracian Нет, это не работает. Компонуемый нижний колонтитул оставил пространство, которое занимали верхние элементы. Вы можете просто увидеть идеальный результат, потому что у вас есть только два верхних элемента, попробуйте добавить больше элементов.

Atul Sharma 08.08.2024 10:00

@Thracian Теперь работа над редактированием outPositions[index] = totalSize - height. Но до этого это вызывало тот же эффект, о котором я упоминал.

Atul Sharma 08.08.2024 10:03

Я знаю, это то, что я написал в комментарии после этого. Вы правы, это было неправильно, но оно не центрировалось в оставшемся пространстве. Использовалась высота других размещенных предметов.

Thracian 08.08.2024 10:05

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