Отменить Snackbar с помощью SwipeToDismissBoxAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Отменить Snackbar с помощью SwipeToDismissBox

Сообщение Anonymous »

Я начинаю использовать Jetpack Compose и пытаюсь реализовать список, в котором вы можете провести пальцем, чтобы удалить элемент, но вы также можете восстановить его с помощью действия Snackbar. В старом мире, основанном на XML-макете, мне удавалось сделать это раньше, но я не могу заставить его работать в Jetpack Compose.
Я могу добавить поведение смахивания для удаления, которое успешно удаляет элемент, и я также могу потом показать Snackbar. Технически вставка элемента обратно в список тоже работает, но проблема, похоже, в том, что метод RememberSwipeToDismissBoxState() запоминает, что я смахнул этот элемент, и сохраняет его состояние. Поэтому, когда элемент повторно вставляется, оператор if, который проверяет состояние, чтобы определить, следует ли удалить элемент, сразу же срабатывает и удаляет элемент снова.
Сам элемент представляет собой объект, сохраненный в базе данных SQLite, к которой я получаю доступ через Room.
Кто-нибудь знает, как или даже если такую функциональность можно реализовать с помощью Compose?
В настоящее время у меня есть следующий код:
/>Список:
@Composable
fun WatchHistory(
viewModel: WatchHistoryViewModel = viewModel(),
navigator: Navigator = Navigator.current,
) {
val entries = viewModel.entries.collectAsLazyPagingItems()
val coroutineScope = rememberCoroutineScope()

val snackbarHostState = remember { SnackbarHostState() }

Scaffold(
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
topBar = {
TopAppBar(
title = {
Text(
text = stringResource(id = R.string.watch_history_title),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.basicMarquee()
)
},
navigationIcon = {
IconButton(onClick = { navigator.back() }) {
Icon(
imageVector = Icons.AutoMirrored.Default.ArrowBack,
contentDescription = null
)
}
},
actions = { WatchHistoryMenu() },
)
},
content = { contentPadding ->
LazyColumn(contentPadding = contentPadding) {
items(count = entries.itemCount, key = entries.itemKey { it.historyId }) { index ->
entries.get(index)?.let { item ->
WatchHistoryItem(
item = item,
onDelete = { id ->
coroutineScope.launch {
viewModel.deleteEntry(id)

val result =
snackbarHostState.showSnackbar("Entry deleted", "Restore")

if (result == SnackbarResult.ActionPerformed) {
viewModel.undoDelete(item.toWatchHistoryEntry())
}
}
}
)
}
}
}
},
contentWindowInsets = WindowInsets.safeDrawing
)
}

Элемент:
@Composable
fun WatchHistoryItem(
item: WatchHistoryVideoEntity,
onDelete: (id: Int) -> Unit,
) {
val swipeToDismissState = rememberSwipeToDismissBoxState()

if (swipeToDismissState.currentValue == SwipeToDismissBoxValue.EndToStart) {
onDelete(item.historyId)
}

SwipeToDismissBox(
state = swipeToDismissState,
backgroundContent = {}
) {
VideoItem(item = item.video)
}
}

Субъекты. Фактическая таблица содержит WatchHistoryEntryEntity, WatchHistoryVideoEntity создается посредством соединения с другой таблицей.
@Entity(tableName = "watchHistory", indices = [Index("watchDate")])
@JsonClass(generateAdapter = true)
data class WatchHistoryEntryEntity(
@PrimaryKey(autoGenerate = true)
override val id: Int = 0,

@Json(name = "episodeId") val videoId: String,
val watchDate: Instant = Instant.now()
) : BaseEntity

data class WatchHistoryVideoEntity(
val historyId: Int,
val watchDate: Instant,

@Embedded val video: VideoEntity
) {
fun toWatchHistoryEntry() = WatchHistoryEntryEntity(
id = historyId,
videoId = video.id,
watchDate = watchDate,
)
}


Подробнее здесь: https://stackoverflow.com/questions/786 ... dismissbox
Ответить

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

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

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

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

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