Event Handling on a Jetpack Compose Card
Asked Answered
O

2

17

I have a music player app - on my screen, I have cards displaying information about tracks. When I tap on one card, the player should play its track.

@Composable
fun TrackCard(track: Track) {
    Card(
        modifier = Modifier.padding(5.dp).fillMaxWidth(),
        contentColor = Color.Black
    ) {
        Column(modifier = Modifier.padding(10.dp)) {
            ArtistName(text = track.artist.name)
            Headline(text = track.title)
            AlbumName(text = track.album.title)
        }
    }
}

I tried it with adding a Clickable on its Modifier like this: clickable(onClick = {}) In order to let the track play, I need another param for my TrackCard, the player itself. As I want to keep UI code separate, I was wondering if I could add an Event Listener and access play the track from there? (Also I would like to catch the different type of events like a long pressed touch etc. for different event handling as well)

The track cards get initialized like this:

@Composable
private fun ResultList(model: PlayerModel) {
    with(model) {
            LazyColumn(state = rememberLazyListState()) {
                items(tracks) {
                    TrackCard(it)
                }
            }
        }
    }
}

How would I accomplish this?

Obliterate answered 23/4, 2021 at 19:25 Comment(0)
C
17

It depends by your MediaPlayer implementation, but you can decouple the card and the media player composables using something like:

val (source, setSource) = remember { mutableStateOf (
    "mediaToPlay")
}

//MediaPlayer(source)
LazyColumn() {
    items(listTrack){
        TrackCard(it, onClickStartSource = {setSource(it.source)})
    }
}

with:

@Composable
fun TrackCard(track: Track, onClickStartSource : () -> Unit) {

    Card(
        modifier = Modifier
            .padding(5.dp)
            .fillMaxWidth(),
         onClick = {onClickStartSource},
            //your code
    ){ /* ... */ }

Also you can use the combinedClickable modifier to get the different click events:

Card(
    modifier = Modifier
        .padding(5.dp)
        .fillMaxWidth()
        //.clickable(onClick = onClickStartSource)
        .combinedClickable(
            onLongClick = { /*....*/ },
            onDoubleClick ={ /*....*/ }),
    contentColor = color
)
Crossways answered 23/4, 2021 at 19:55 Comment(2)
.combinedClickable is such a lifesaver ..I'll definitely be using it in my own projectsAmye
@Amye @Obliterate just a final note: combinedClickable is currently (1.0.0-beta05) marked as @ExperimentalFoundationApiCrossways
A
23

You can add a click event to a Card like this. Put the code you would want to include for the click inside the clickable function

Card(
modifier = Modifier.padding(5.dp).fillMaxWidth().clickable{ },
        contentColor = Color.Black       
    )
Amye answered 23/4, 2021 at 19:48 Comment(0)
C
17

It depends by your MediaPlayer implementation, but you can decouple the card and the media player composables using something like:

val (source, setSource) = remember { mutableStateOf (
    "mediaToPlay")
}

//MediaPlayer(source)
LazyColumn() {
    items(listTrack){
        TrackCard(it, onClickStartSource = {setSource(it.source)})
    }
}

with:

@Composable
fun TrackCard(track: Track, onClickStartSource : () -> Unit) {

    Card(
        modifier = Modifier
            .padding(5.dp)
            .fillMaxWidth(),
         onClick = {onClickStartSource},
            //your code
    ){ /* ... */ }

Also you can use the combinedClickable modifier to get the different click events:

Card(
    modifier = Modifier
        .padding(5.dp)
        .fillMaxWidth()
        //.clickable(onClick = onClickStartSource)
        .combinedClickable(
            onLongClick = { /*....*/ },
            onDoubleClick ={ /*....*/ }),
    contentColor = color
)
Crossways answered 23/4, 2021 at 19:55 Comment(2)
.combinedClickable is such a lifesaver ..I'll definitely be using it in my own projectsAmye
@Amye @Obliterate just a final note: combinedClickable is currently (1.0.0-beta05) marked as @ExperimentalFoundationApiCrossways

© 2022 - 2024 — McMap. All rights reserved.