I have this composable:
@Composable
inline fun <T:Any> AnimatedVisibilityNullable(
value: T?,
...
crossinline content: @Composable (T) -> Unit
) {
// for nullable values
val ref=remember{ Ref<T>() }
LaunchedEffect(value){
ref.value = value?:ref.value
}
// content
AnimatedVisibility(
value!=null && visible(value),
...
){
ref.value?.let { value ->
content(value)
}
}
}
When the value its not null, display the content and pass the parameter value null-safe. I want to know if there's a way to do it more generic? Something like this, but with generic types and vararg:
@Composable
fun <T1:Any,T2:Any> AnimatedVisibilityNullable(
value1: T1?,
value2: T2?,
...
content: @Composable (T1,T2) -> Unit
) {
// for nullable values
val ref1 = remember { Ref<T1>() }
val ref2 = remember { Ref<T2>() }
LaunchedEffect(value1,value2) {
ref1.value = value1?:ref1.value
ref2.value = value2?:ref2.value
}
// content
AnimatedVisibility(
value1!=null && value2!=null,
...
){
ref1.value?.let {p1->
ref2.value?.let { p2 ->
content(p1,p2)
}
}
}
}
For what i search, its not possible in kotlin, al least there is no syntax for this case. Thanks!
I have no clue what your code does or why you even want to do that, but if you just want your function to work with vararg parameters the best you can get will probably be something like this:
@Composable
fun <T : Any> AnimatedVisibilityNullable(
vararg values: T?,
// ...
content: @Composable (List<T>) -> Unit,
) {
// for nullable values
val refs = values.associateWith {
remember { Ref<T>() }
}
LaunchedEffect(*values) {
refs.forEach { (value, ref) ->
ref.value = value ?: ref.value
}
}
// content
AnimatedVisibility(
visible = values.all { it != null }
// ...
) {
val nonNullRefs = refs.values.mapNotNull { it.value }
if (nonNullRefs.size == refs.size) {
content(nonNullRefs)
}
}
}
Since lambdas cannot have vararg parameters I changed its parameter to a List instead. Also keep in mind that the type inference cannot distinguish each separate type in the varargs parameter (or the List), so it will have the combined supertype of all parameters. That probably won't be a problem since the actual type doesn't seem to be needed anywhere.
As I already said, I do not understand the code, but there are some fishy parts that you might want to take a look at:
Ref
? It doesn't seem to add anything that cannot be achieved by a simple variable.visible(value)
which your second example does not. If that is still needed you may want to use values.all { it != null && visible(it) }
instead.