Лучшая практика в составе для визуализации множества данных с использованием изменяющихся состоянийAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Лучшая практика в составе для визуализации множества данных с использованием изменяющихся состояний

Сообщение Anonymous »

Моя проблема в том, что у меня много данных, и я хочу отображать его в JetPack Compose в таблице, когда я могу изменить эти данные.
моя ситуация
Допустим, у меня есть класс, называемый пользователем , с именем и некоторым чучело PrettyPrint-Override ">

Код: Выделить всё

class User (
var firstName: String,
var lastName: String,
var foo: Int
)
< /code>
Тогда у меня есть список, содержащий утраченных пользователей. Для этого примера давайте просто предположим, что у меня есть список из 100 парней по имени «Джон Сина» со значением Foo 
0:

Код: Выделить всё

val users = List(100) {
User("John", "Cena", 0)
}
< /code>
Теперь я хочу представить этих пользователей в таблице. Таким образом, каждый пользователь получает строку, как это: < /p>
@Composable
fun UserRow(user: User) = Row {
Text(user.firstName)
Text(user.lastName)
Text(user.foo.toString())
}
< /code>
И, наконец, мы отображаем такую строку для всех 100 пользователей в нашем списке: < /p>
@Composable
fun UserTable(users: List) = LazyColumn {
items(users) { user ->
UserRow(user)
}
}
< /code>
И мы называем это так в окне: < /p>
UserTable(users)
Теперь я хочу что-то изменить с фронта.

Код: Выделить всё

@Composable
fun UserRow(user: User) = Row {
Text(user.firstName)
Text(user.lastName)
Text(
text = user.foo.toString(),
modifier = Modifier.clickable {
user.foo += 1
}
)
}
Однако это не отобразит новое значение как user.foo не является mutablestate . Итак, вот некоторые подходы к тому, как решить проблему, но все они не кажутся идеальными для меня. < /P>
возможные решения < /h1>
1. Сделайте user.foo изменяемое состояние
Измените определение класса пользователя на:

Код: Выделить всё

class User (
var firstName: String,
var lastName: String,
foo: Int
) {
var foo by mutableStateOf(foo)
}
Pros: никаких других изменений, я могу работать с foo , как с нормальным значением Int.
cons: Пользователь класс также является частью бизнес -логики, и он чувствует себя неправильно, чтобы использовать Mutablestate , когда он не связан с Compose. Я думаю, что было бы лучше использовать обычный int s в бэкэнде.
2. Вручную запустите переоборудование
Оберните текст foo в ключ Как это:

Код: Выделить всё

@Composable
fun UserRow(user: User) = Row {
Text(user.firstName)
Text(user.lastName)

var updater by remember { mutableStateOf(false) }
key(updater) {
Text(
text = user.foo.toString(),
modifier = Modifier.clickable {
user.foo += 1
updater = !updater
}
)
}
}
Теперь, каждый раз, когда изменяется Updater , запускается переоборудование. Не влияет на бизнес -логику.
минусы: очень уродливо, так как вам приходится вручную изменить обновление , а также определенно не предполагаемый способ.
3. Используйте отдельную переменную для удержания отображаемого текста
Мы также можем удерживать отображаемое значение в отдельном mutablestate :

Код: Выделить всё

@Composable
fun UserRow(user: User) = Row {
Text(user.firstName)
Text(user.lastName)

var fooText by remember { mutableStateOf(user.foo.toString()) }
Text(
text = fooText,
modifier = Modifier.clickable {
user.foo += 1
fooText = user.foo.toString()
}
)
}
pros: четкое разделение пользовательского интерфейса и бизнес -логики
минусы: по -прежнему требует ручного обновления, хотя это не так уродливо, как 2 -е решение. самый чистый / предназначенный способ сделать это. Что вы думаете об этих решениях, и есть ли лучше? Тем не менее, это будет работать для этого примера, но я думаю, что это не для моего фактического варианта использования. Этот метод более сложный, а затем просто переназначает foo , он, возможно, сделает некоторую проверку ввода, изменит другие не примитивные атрибуты пользователя, сделает вызовы в базу данных и, возможно, другие вещи:

Код: Выделить всё

class User (
var firstName: String,
var lastName: String,
var foo: Int,
var someOtherObject: SomeOtherClass

) {
fun changeFoo(newFoo: Int) {
if (foo > 9999) {
someError()
}
foo = newFoo
// make changes to other objects
someOtherObject.doSomething()
// some additional effects
doSqlStuff(this)
andWhatnot()
// ..
}
}
< /code>
Я хочу иметь возможность вызвать этот метод изнутри Compose или где -то внутри бизнес -логики без отношения к составлению. Он загружается из базы данных SQLite при запуске, и всякий раз, когда я меняю список пользователей, в базе данных SQLite должны быть сделаны те же изменения. Поэтому просто вызов копии 
не будет обновлять базу данных, вместо этого я хотел бы вызвать метод изменения и кода>, чтобы сохранить его проще. Если это так, я буду использовать два разных метода для составления и не сопоставления областей, либо использовать один из подходов к обновлению ручного обновления. (В моем случае это на самом деле комплексный мультиплатформенный проект).
Извините за то, что опубликовал вопрос, похожий на старый, я просто подумал, что старый был плохим и не решил фактическую проблему, которую я имел (я думаю)

Подробнее здесь: https://stackoverflow.com/questions/797 ... ble-states
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»