JetPack Compose. Почему передаваемые данные DragAndDropSource не отражают новое состояние после рекомпозиции?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 JetPack Compose. Почему передаваемые данные DragAndDropSource не отражают новое состояние после рекомпозиции?

Сообщение Anonymous »

У меня есть список элементов, каждый из которых использует Modifier.draganddropsource для публикации ClipData для некоторых целей на одном экране. Когда элемент перетаскивается на цель, он удаляется из исходного списка, и список перестраивается. На экране все выглядит нормально (новый список рисуется с объединенным элементом). Но когда я перетаскиваю следующий элемент в списке (ниже того, который я только что извлек), его ClipData по-прежнему представляет предыдущий (удаленный) элемент, и цель думает, что снова получает старый элемент.
Компонуемый источник:

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

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ItemView(
modifier: Modifier = Modifier,
item: String
) {

val clipState: String by remember(item) {
derivedStateOf { item }
}

//    val transferData:  suspend DragAndDropSourceScope.() -> Unit by remember(item) {
//        Log.d("ItemView", "recomposing derived draganddrop for $item")
//
//        derivedStateOf {
//            {
//            detectTapGestures(onPress = {
//                Log.d("Source", "starting to drag ${item}")
//                startTransfer(DragAndDropTransferData(
//                    ClipData.newPlainText("product", item),
//                    flags = View.DRAG_FLAG_OPAQUE
//                ))
//            })
//
//        }}
//    }

Box(
modifier = modifier
//.dragAndDropSource(block = transferData)
.dragAndDropSource {

detectTapGestures(onPress = {
Log.d("Source", "starting to drag ${item}")
startTransfer(DragAndDropTransferData(
ClipData.newPlainText("product", item),
localState = clipState,
flags = View.DRAG_FLAG_OPAQUE
),
)
})
}
.fillMaxWidth()
.height(48.dp),
contentAlignment = Alignment.CenterStart
) {
Text(
text = item,
color = Color.Black
)
}
Обратный вызов Target:

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

class Callback(val index: Int): DragAndDropTarget {
...

override fun onDrop(event: DragAndDropEvent): Boolean {
return try {
event.toAndroidDragEvent().localState.also {  Log.d("Target", "localState: $it") }
event.toAndroidDragEvent().clipData.getItemAt(0).text.toString()
.also {
Log.d("Target", "drop $it to $index")
onDrop(index, it)
}
insertIndex = null
true
} catch (e: Exception) {
Log.e("DropCallback", "failed parse data", e)
false
}
}
...
}
В комментариях вы можете видеть, что я пытался сохранить TransferData, а затем и весь исходный блок в запомненном состоянии, отключенном от элемента, но это не дало никакого эффекта. Я не мог понять, как сохранить функцию onPress таким образом.
Элемент меняется, потому что компоновка на экране показывает правильный текст. Но каждый оператор журнала в источнике и цели отражает старое состояние этого составного объекта, ЗА ИСКЛЮЧЕНИЕМ оператора «перекомпоновки производного перетаскивания», который показывает правильный новый элемент (все оставшиеся элементы пересоставляются после изменения списка, это просто карта функция, а не LazyColumn). Интересно, что все элементы в других местах списка работают правильно — только один элемент ниже, где список был изменен, имеет эту проблему, но она сохраняется, так что по мере перемещения большего количества элементов все больше оставшихся имеют неверные данные. В любом случае, я не эксперт по состояниям, рекомпозиции и т. д., поэтому надеюсь, что вы сможете указать на что-то, что я упустил из виду. Спасибо

Подробнее здесь: https://stackoverflow.com/questions/790 ... -new-state
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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