https://kotlinlang.org logo
#compose
Title
# compose
s

semoro

02/15/2021, 6:41 PM
Passing keys all round is very inconvenient and error prone, is there a better way to perform item list recompositions?
a

Andrey Kulikov

02/15/2021, 6:44 PM
could you please explain a bit more what you currently have and what you don’t like about it? thanks
s

semoro

02/15/2021, 6:55 PM
Mostly errors that I see, is when some outer to LazyColum state changes, and then accidentally used within item, which results in wrong positional memoization Like:
Copy code
@Composable
fun CCaller() {
    var list by remember { mutableStateOf<List<CartItem>>(listOf()) }
    
    CComposable(list = list, onRemove = { 
        list = list - list.last()
    })
}

@Composable
fun CComposable(list: List<CartItem>, onRemove: () -> Unit) {
    LazyColumn {
        items(list) {
            Box(Modifier.pointerInput(it) { 
                this.detectDragGestures(
                    onDragEnd = { onRemove() },
                    onDrag = { _, _ -> }
                )
            })
        }
    }
}
a

Andrey Kulikov

02/15/2021, 6:59 PM
does this bug looks like the same issue as you experience? https://issuetracker.google.com/issues/163069767
s

semoro

02/15/2021, 7:07 PM
No, problem here is that onRemove within pointerInput not get recomposed, and by this containing old list, for items that doesn't changed
I guess problem here is that Modifier.pointerInput has it as key, which is CartItem, and doesn't depend on onRemove itself, but still it is kinda hard to debug such problems
So, fix to me was to change key to
onRemove
a

Andrey Kulikov

02/15/2021, 7:14 PM
oh, yes, it is what you need. you will need it regardless of LazyColumn
s

semoro

02/15/2021, 7:54 PM
Sure, and that's I find a problem, because in my case
Copy code
Box(Modifier.pointerInput(it) { 
                this.detectDragGestures(
                    onDragEnd = { onRemove() },
                    onDrag = { _, _ -> }
                )
            })
Was deep in sub components And that's why it was very hard to debug and fix such problems, and a reason I asking
a

Andrey Kulikov

02/15/2021, 8:06 PM
I agree with you that probably some lint rule for Modifier.pointerInput() for cases like this can help with fixing such issues
l

louiscad

02/17/2021, 2:24 PM
Is there any open issue for that?
a

Andrey Kulikov

02/17/2021, 3:17 PM
from what I aware no, feel free to file one
l

louiscad

02/17/2021, 3:26 PM
@semoro Would you since you have all the details on the use case? I'll star it.
s

semoro

02/18/2021, 11:18 AM
But still, why it is not recomposed automatically?
Yep, I'll create an issue
👀 1
a

Andrey Kulikov

02/18/2021, 12:20 PM
it is not about not recomposing. what you pass to Modifier.pointerInput is a suspend function. we can’t just restart it automatically, so you have to provide a hint on when something really important for the function has been changed. see more details in the kdocs: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]tFilter.kt;l=120;drc=07e0987038a2d1792fcd98944c79e7ae775a6eb5
l

louiscad

02/18/2021, 1:14 PM
The link points to a constant, not a KDoc 🤔
a

Andrey Kulikov

02/18/2021, 2:45 PM
yeah, it is a error used in the intentionally deprecated method. anyway, I meant this and the docs on the method itself