'Composables can only be invoked from the context of a composable context
I'm building an application jetpack compose , after fetch some data from online source , i want to pass an id to as extras to the next screen so that i can call the next request api , but i'm facing two issues , the first issue is that showing me an error that composables can only be invoked from a composable context and the second issue is that i'm not sure wether i'm writing the correct code for calling the next screen , i appreciate any help , Thank you .
- This is my code
val lazyPopularMoviesItems = movies.collectAsLazyPagingItems()
LazyVerticalGrid(cells = GridCells.Fixed(2)) {
items(lazyPopularMoviesItems.itemCount) { index ->
lazyPopularMoviesItems[index]?.let {
Card(elevation = 8.dp, modifier = Modifier
.height(200.dp)
.padding(10.dp)
.clickable {
// This is the function i want to call and pass extras with it
DetailsScreen(movieViewModel = movieViewModel, movieId = it.id)
}
.clip(RoundedCornerShape(8.dp))) {
Column {
Image(
painter = rememberImagePainter("http://image.tmdb.org/t/p/w500/" + it.backdrop_path),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.height(150.dp)
)
Text(
modifier = Modifier
.height(50.dp)
.padding(3.dp)
.fillMaxWidth(),
text = it.title,
fontSize = 15.sp,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
textAlign = TextAlign.Center,
color = androidx.compose.ui.graphics.Color.Black
)
}
}
}
}
}
- MainActivity Code
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val movieViewModel : MovieViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
Scaffold(
backgroundColor = Color.Blue.copy(0.1f),
topBar = { TopAppBar(title = {Text(text = "Movie Flex")}, backgroundColor = Color.White, elevation = 10.dp)},
bottomBar = {
val items = listOf(
BarItems.Popular,
BarItems.Playing,
BarItems.Top,
BarItems.Upcoming
)
BottomNavigation(backgroundColor = Color.Gray) {
items.forEach { item ->
BottomNavigationItem(
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = item.title)},
label = { Text(text = item.title)},
selectedContentColor = Color.White,
alwaysShowLabel = true,
selected = false,
unselectedContentColor = Color.White.copy(0.5f),
onClick = {
navController.navigate(item.route){
navController.graph.startDestinationRoute?.let { route ->
popUpTo(route) {
saveState = true
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
}
})
}
}
},
content = {
ScreenNavigation(navController,movieViewModel)
},
)
}
}
}
@OptIn(ExperimentalCoilApi::class)
@Composable
fun ScreenNavigation(navController: NavHostController,movieViewModel: MovieViewModel){
NavHost(navController = navController, startDestination = BarItems.Popular.route){
composable(route = BarItems.Popular.route){
PopularScreen(movies = movieViewModel.getPopular(), movieViewModel = movieViewModel)
}
composable(route = BarItems.Playing.route){
PlayingScreen(movies = movieViewModel.getPlaying())
}
composable(route = BarItems.Top.route){
TopRatedScreen(movies = movieViewModel.getTopRated())
}
composable(route = BarItems.Upcoming.route){
UpcomingScreen(movies = movieViewModel.getUpcoming())
}
}
}
- Navigation Routing
sealed class BarItems(var route : String , var icon : Int , var title : String) {
object Popular : BarItems("popular", R.drawable.ic_baseline_remove_red_eye_24,"Popular")
object Playing : BarItems("playing",R.drawable.ic_baseline_remove_red_eye_24,"Playing")
object Top : BarItems("top",R.drawable.ic_baseline_remove_red_eye_24,"Top")
object Upcoming : BarItems("upcoming",R.drawable.ic_baseline_remove_red_eye_24,"Upcoming")
}
Solution 1:[1]
As you've pointed out, we'll need two things:
- Handle the navigation. You can use navigation-compose. Have a look at the documentation
- Trigger the navigation with either a
LaunchedEffector by launching a coroutine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Stephen Vinouze |
