I'm working on an Android app using Kotlin. The app uses fragment-based navigation but I am using some Jetpack Compose to build some elements of it instead of using RecyclerViews and such.
Right now I have a card composable that builds itself off an object and another one that creates a list of those with a LazyColumn. The card has it's own separate file but the list composable is part of the code of the fragment that uses it. This is because when one of the cards is clicked, it calls a function to load a fragment that lists the details of the object the card represents (Events in this case).
This is the code in my list fragment:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_liste_evenement,container,false).apply {
val listeEvens : ArrayList<Événement> = ArrayList<Événement>()
listeEvens.add(évén)
listeEvens.add(évén2)
listeEvens.add(évén3)
val composeView = findViewById<ComposeView>(R.id.listeBlocsEven)
composeView.setContent {
ListeCarteÉvénements(événements = listeEvens)
}
}
}
@Composable
fun ListeCarteÉvénements(événements: List<Événement>) {
LazyColumn {
items(événements) { e ->
CarteÉvénement(événement = e,clickEvent = { loadFragment(details_evenement(e)) })
}
}
}
This is the card composable's declaration:
@Composable
fun CarteÉvénement(événement: Événement,clickEvent: () -> Unit) {
Column(modifier = Modifier
.clip(RectangleShape)
.padding(all = 8.dp)
.fillMaxWidth()
.height(300.dp)
.background(MaterialTheme.colors.primaryVariant)
.clickable(onClick = clickEvent))
private fun loadFragment(fragment: Fragment) {
val transaction = requireActivity().supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragmentContainerView, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
As you can see, doing it this way allows me to get direct access to the event cards so that I can give my details fragment the clicked event as an attribute.
This all works but my question is: If I wanted to put the list composable in the same file as the card(outside of the fragment), how would I pass it the loadFragment function that receives a fragment that also has it's own parameter(in this case the event from the clicked card)?
CodePudding user response:
You can pass a lambda callback to ListeCarteÉvénements
which receives the event as an argument.
override fun onCreateView (...) : View {
...
composeView.setContent {
ListeCarteÉvénements(
événements = listeEvens,
onItemClick = { e -> loadFragment(details_evenement(e)) }
)
}
...
}
@Composable
fun ListeCarteÉvénements(événements: List<Événement>, onItemClick: (Événement) -> Unit {
LazyColumn {
items(événements) { e ->
CarteÉvénement(événement = e,clickEvent = { onItemClick(e) })
}
}
}