How to pass a composable content parameter in data class

Viewed 1295

I need to pass a compose content parameter in data class. For example a button can render when added into this content.

data class ContentData {
  val content: @Composable ()-> Unit
}

This is working but when I get the app background I am getting parcelable exception. How to solve this problem.

1 Answers

One possible explanation I think that will occur related with a parcelable error, happens if you try to pass such object between activities as extras through Intent. Consider not use Composable as parameters in objects. Instead, try to represent the parameters of your Composable with a model which contains the parameters.

// your compose function
@Composable
fun Item(content: String = "Default", padding: Dp){
    // ...
}

// Ui Model which contains your data (instead of have a weird composable reference) as a parcelable. 
data class ContentData(
    val content: String = "Default",
    val paddingRaw: Int = 0
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString().orEmpty(),
        parcel.readInt()
    ) {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(content)
        parcel.writeInt(paddingRaw)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<ContentData> {
        override fun createFromParcel(parcel: Parcel): ContentData {
            return ContentData(parcel)
        }

        override fun newArray(size: Int): Array<ContentData?> {
            return arrayOfNulls(size)
        }
    }
}

// Example if you need the model between activities through the intent as an extra.
val data = ContentData("your content", 11)
val intent = Intent().apply {
    putExtra("keyContentData", data)
}

//The way of get and use your model.
val contentData = intent.extras?.get("keyContentData") as ContentData

@Composable
fun ParentComponent(){
    // ...

        Item(
            contentData?.content.orEmpty(),
            contentData?.paddingRaw?.dp ?: 0.dp
        )
    // ...
}
Related