I try to learn jetpack compose these days, and I have a simple project in jetpack compose, bottom sheet work in my project, but when I use bottom navigation, it is not work, I search in many website and stackoverflow especially, but I did not find any solution, I do not know what I missed? is there any idea?
#Composable
fun BSDataScreen() {
val modalBottomSheetState = rememberModalBottomSheetState(initialValue =
ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
ModalBottomSheetLayout(
sheetContent = {
SheetScreen()
},
sheetState = modalBottomSheetState,
sheetShape = RoundedCornerShape(topStart = 15.dp, topEnd = 15.dp),
sheetBackgroundColor = Color.White,
) {
Scaffold(
backgroundColor = Color.White,
) {
DataScreen(
scope = scope, state = modalBottomSheetState)}}}
#Composable
fun DataScreen(
scope: CoroutineScope,
state: ModalBottomSheetState
) {
val listOfData = listOf(
Data( painterResource(R.drawable.image1)),
Data(painterResource(R.drawable.image2)),
Data(painterResource(R.drawable.image3),)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
LazyColumn(
modifier = Modifier
) {
items(listOfData.size) { index ->
DataListItem(listOfData[index]) data: Data->
scope.launch {
state.show()
}
}}}}
#Composable
fun DataListItem(data: Data, onLongClick: (Data) -> Unit) {
val context = LocalContext.current
Column(
modifier = Modifier.padding(5.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
.combinedClickable(
onLongClick= {
onLongClick(data)
},)
) {
Image(
painter = data.painter,
contentDescription = null,)}}}
BottomNav:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MainScreen()
}
}
}
#Composable
fun MainScreen() {
val navController = rememberNavController()
Scaffold(
bottomBar = { BottomNavigationBar(navController) }
) {
Navigation(navController = navController)
}
}
#Composable
fun Navigation(navController: NavHostController) {
val modalBottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
NavHost(navController, startDestination = NavigationItem.Data.route) {
composable(NavigationItem.Data.route) {
DataScreen(
scope = scope, state = modalBottomSheetState
)
}
composable(NavigationItem.Data2.route) {
Data2Screen()
}
composable(NavigationItem.Data3.route) {
Data3Screen()
}
composable(NavigationItem.Data4.route) {
Data4Screen()
}
composable(NavigationItem.Data5.route) {
Data5Screen()
}
}
}
#Composable
fun BottomNavigationBar(navController: NavController
) {
val items = listOf(
NavigationItem.Data,
NavigationItem.Data2,
NavigationItem.Data3,
NavigationItem.Data4,
NavigationItem.Data5
)
BottomNavigation(
backgroundColor = colorResource(id = R.color.white),
contentColor = colorResource(id = R.color.black)
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
items.forEach { item ->
BottomNavigationItem(
icon = {
Icon(
painterResource(id = item.icon),
contentDescription = null
)
},
selectedContentColor = colorResource(id = R.color.red),
unselectedContentColor = colorResource(id = R.color.blue),
alwaysShowLabel = true,
selected = currentRoute == item.route,
onClick = {
navController.navigate(item.route) {
navController.graph.startDestinationRoute?.let { route ->
popUpTo(route) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}})}}}
I think your problem is your bottom sheets appear under bottom bar. The same thing I solved is very simple.
#Composable
fun SettingView() {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
Scaffold(
bottomBar = {
BottomBar(navController = navController)
},
content = {
Box(modifier = Modifier.padding(it)) {
BottomNavGraph(
navController = navController,
scaffoldState = scaffoldState
)
}
}
)
}
content screens wrap with Box and padding to scaffold's PaddingValues.
Just wrap the whole screen with ModalBottomSheetLayout.
You can put the following code:
Scaffold(
bottomBar = { BottomNavigationBar(navController) }
) {
Navigation(navController = navController)
}
inside
ModalBottomSheetLayout(...){
Scaffold(
bottomBar = { BottomNavigationBar(navController) }
) {
Navigation(navController = navController)
}
}
Try using the Navigation Material library provided by Accompanist.
https://google.github.io/accompanist/navigation-material/
Related
Hello stack overflow community.
I would like to pass (data class AndroidItem) parameter to Nav function inside MainActivity Class without empty data, how can i do? it must be like this (data) not (data = ) and it shows error (No value passed for parameter 'data').
i have tried but unfortunately i could not do. I know that there is similar questions about this subject but i want to help me right now
Here my code:
class MainActivity : ComponentActivity() {
#OptIn(ExperimentalMaterialApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Diwaanka2022Theme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
// here it must be like (data) only not (data = )
Nav(data = )
}
}
}
}
}
#Composable
data class AndroidItem(
val ID: Int?,
val ItemType: String?,
val Price: Int?,
)
#Composable
fun Nav(data: AndroidItem) {
val context = LocalContext.current
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Screen.LoginScreen.route
) {
composable(
route = "Search_Screen_Details/{name}",
arguments = listOf(
navArgument(name = "name") {
type = NavType.StringType
}
)
) {
backStackEntry ->
eee(
navController,
myName = backStackEntry.arguments?.getString("name"),
data
)
}
}
}
#OptIn(ExperimentalMaterialApi::class)
#Composable
fun eee(navController: NavController, myName: String?, data: AndroidItem) {
val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()
BottomSheetScaffold(
scaffoldState = scaffoldState,
sheetPeekHeight = 0.dp,
sheetContent = {
Column(
Modifier
.fillMaxWidth()
.height(500.dp)
.padding(15.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
val context = LocalContext.current
Text(
text = data.ID.toString(),
fontSize = 25.sp,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 20.dp),
textAlign = TextAlign.Center
)
Button(onClick = {
}) {
Text(text = "welcome", fontSize = 22.sp)
}
Spacer(modifier = Modifier.height(10.dp))
}
}
) {
Search_Screen_Details(navController, myName, scaffoldState)
}
}
#OptIn(ExperimentalMaterialApi::class)
#SuppressLint("MutableCollectionMutableState")
#Composable
fun Search_Screen_Details(
navController: NavController,
myName: String?,
scaffoldState: BottomSheetScaffoldState
) {
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
val context = LocalContext.current
if(myName == "all") {
val baseUrl = "https://adeega.xisaabso.online/Api/android_all_customers_all.php"
val android = Android()
val data = remember {
mutableStateOf(Android())
}
val stringRequest = StringRequest(baseUrl, { it ->
val gsonBuilder = GsonBuilder()
val gson = gsonBuilder.create()
gson.fromJson(it, Array<AndroidItem>::class.java)?.forEach {
android.add(it)
}
data.value = android
}, {
Toast.makeText(context, it.toString(), Toast.LENGTH_LONG).show()
}).apply {
LazyColumn(
contentPadding = PaddingValues(12.dp)
) {
items(data.value) { item ->
MyCard(
data = item,
navController
)
}
} // END LazyColumn
}// StringRequest
val volleyRequest = Volley.newRequestQueue(context)
volleyRequest.add(stringRequest)
}
} // END Column
}
#OptIn(ExperimentalMaterialApi::class)
#Composable
fun MyCard(
data : AndroidItem,
navController: NavController,
scaffoldState: BottomSheetScaffoldState
) {
Card(
modifier = Modifier
.fillMaxWidth(),
RoundedCornerShape(10.dp),
elevation = 5.dp,
) {
Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
modifier = Modifier
.padding(15.dp)
) {
Column() {
Text(
text = data.ID.toString(),
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "Price: $" + data.Price,
fontSize = 19.sp,
fontWeight = FontWeight.Bold
)
}
}//END Row
} //END Card
}
I am currently using a navigation drawer in jetpack compose, but I have encountered a problem. When I added the navigation drawer to the mainDrawerScreen, it was displaying for every screen I added, in my case it said "Main Menu" for every screen composable when navigated to. This is not ideal.
I decided to remove TopAppBar from mainDrawerScreen and create a seperat scaffold with the TopAppBar for each composable screen. However, now the navigation does not work. I tried to create a trailing lambda for navigation but might have done it the wrong way. Anyone got a suggestion to why it is not opening the navDrawer ? Appreciate the feedback!
MainDrawerSCreen:
#SuppressLint("UnusedMaterialScaffoldPaddingParameter")
#Composable
fun MainDrawerScreen() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
val navController = rememberNavController()
Scaffold(
scaffoldState = scaffoldState,
drawerContent = {
DrawerHeader()
DrawerLayout(scope = scope, scaffoldState = scaffoldState , navController = navController)
}
) {
Navigation(navController = navController) // TODO This controls the navigation between different screens
}
}
My seperate created TopAppBar:
#Composable
fun TopAppBar1(
scope: CoroutineScope,
scaffoldState: ScaffoldState,
text: String,
onIconClick: () -> Unit
) {
TopAppBar(
title = { Text(text = text, fontSize = 18.sp) },
navigationIcon = {
IconButton(onClick = {
scope.launch {
withContext(Dispatchers.IO) { // should I keep this coroutine on background thread ?
scaffoldState.drawerState.open()
}
}
}) {
Icon(
Icons.Filled.Menu, "Menu",
Modifier.clickable { onIconClick.invoke()})
}
},
backgroundColor = LightBlue,
contentColor = MaterialTheme.colors.onPrimary,
)
}
ProfileScreen:
#SuppressLint("UnusedMaterialScaffoldPaddingParameter")
#Composable
fun ProfileScreen1() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
Scaffold(
topBar = {
TopAppBar1(scope = scope, scaffoldState = scaffoldState, text = "Profile") {
scope.launch { scaffoldState.drawerState.currentValue } <----------- Trailing Lambda
}
},
content = {
ActualBackground() // Background
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) { // Content }
I show you what I did :
TopAppBar.kt :
#Composable
fun TopAppBarScreen(
title: String = "",
screen: String,
navController: NavController
) {
TopAppBar(
title = {
Text(
text = title,
style = Typography.h2
)
},
navigationIcon = {
IconButton(
onClick = {
navController.navigate(screen)
}
) {
Icon(Icons.Filled.ArrowBack, "backIcon")
}
},
backgroundColor = Color.Background,
contentColor = Color.BackgroundDarkGrey,
elevation = 0.dp,
)
}
Navigation.kt
#Composable
fun Navigation() {
val navController = rememberNavController()
val viewModel = hiltViewModel<CountrySelectorViewModel>()
val userViewModel = InputViewModel(LocalContext.current)
NavHost(
navController = navController,
startDestination = Screen.WELCOME_SCREEN
) {
composable(Screen.WELCOME_SCREEN) {
WelcomeScreen(navController = navController)
}
}
Screen :
object Screen {
const val WELCOME_SCREEN = "WelcomeScreen"
}
When I call my TopAppBar :
TopAppBarScreen(
screen = Screen.WELCOME_SCREEN,
navController = navController
)
Look at how the navigation works and it's the same if you are using a button to change screen.
I hope this can help you
I have a custom search bar will not allow me to place a cursor and type text into it. Before adding the viewmodel and state, I was able to have the TextField work and allow typing text into it.
I've tried using state variables within the composable instead of separating the logic into the view model and unfortunatly recieved the same result. I have a feeling it's something simple that I'm missing but can't quite find it.
Custom Search Bar:
#Composable
fun SearchBar(
modifier: Modifier,
viewModel: ToolSetListViewModel = hiltViewModel()
){
Surface (
modifier = modifier
.fillMaxWidth()
.height(74.dp)
.padding(20.dp, 15.dp, 20.dp, 0.dp),
elevation = 10.dp,
color = MaterialTheme.colors.primary,
shape = RoundedCornerShape(25)
){
TextField(
modifier = modifier
.fillMaxWidth(),
value = viewModel.searchText,
onValueChange = {
viewModel.onEvent(ToolSetListEvent.OnSearchToolSet(it))
},
placeholder = {
Text(
modifier = modifier
.alpha(ContentAlpha.medium),
text = "Search...",
color = White
)
},
textStyle = TextStyle(
fontSize = MaterialTheme.typography.subtitle1.fontSize,
),
singleLine = true,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
cursorColor = White
)
)
}
Screen:
#Composable
fun ToolSetListScreen(
onNavigate: (UiEvent.Navigate) -> Unit,
viewModel: ToolSetListViewModel = hiltViewModel()
) {
val toolSets = viewModel.toolSets.collectAsState(initial = emptyList())
LaunchedEffect(key1 = true) {
viewModel.uiEvent.collect { event ->
when(event) {
is UiEvent.Navigate -> onNavigate(event)
}
}
}
Scaffold (
floatingActionButton = {
FloatingActionButton(onClick = {
viewModel.onEvent(ToolSetListEvent.OnAddToolSetClick)
}) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add")
}
}
) {
SearchBar(
modifier = Modifier,
)
LazyColumn(
modifier = Modifier.fillMaxSize()
.padding(0.dp, 20.dp)
) {
items(toolSets.value) { toolset ->
ToolSetItem(
toolSet = toolset,
onEvent = viewModel::onEvent,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable {
viewModel.onEvent(ToolSetListEvent.OnToolSetClick(toolset))
}
)
}
}
}
}
ViewModel:
#HiltViewModel
class ToolSetListViewModel #Inject constructor(
private val repository: ToolSetRepository
): ViewModel() {
val toolSets = repository.getAllToolSets()
private val _uiEvent = Channel<UiEvent>()
val uiEvent = _uiEvent.receiveAsFlow()
var searchText by mutableStateOf("")
private set
fun onEvent(event: ToolSetListEvent) {
when(event) {
is ToolSetListEvent.OnToolSetClick -> {
sendUiEvent(UiEvent.Navigate(Routes.ADD_EDIT_TOOL_SET + "?PONumber=${event.toolSet.PONumber}"))
}
is ToolSetListEvent.OnDeleteToolSetClick -> {
viewModelScope.launch {
repository.deleteToolSet(event.toolset)
}
}
is ToolSetListEvent.OnAddToolSetClick -> {
sendUiEvent(UiEvent.Navigate(Routes.ADD_EDIT_TOOL_SET))
}
is ToolSetListEvent.OnSearchToolSet -> {
viewModelScope.launch {
if (event.searchText.isNotBlank()) {
searchText = event.searchText
repository.getToolSetByPO(event.searchText)
}
}
}
}
}
private fun sendUiEvent(event: UiEvent) {
viewModelScope.launch {
_uiEvent.send(event)
}
}
MainActivity:
#AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PunchesManagerTheme {
val navController = rememberNavController()
Scaffold (
content = {
Navigation(navController)
},
bottomBar = { BottomNavigationBar(navController = navController) },
)
}
}
}
}
#Composable
fun BottomNavigationBar(navController: NavHostController) {
BottomNavigation {
val backStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = backStackEntry?.destination?.route
NavBarItems.bottomNavItem.forEach { navItem ->
BottomNavigationItem(selected = currentRoute == navItem.route, onClick = {
navController.navigate(navItem.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = false
}
launchSingleTop = true
restoreState = true
}
},
icon = {
Icon(imageVector = navItem.icon,
contentDescription = navItem.name)
},
label = {
Text(text = navItem.name)
},
)
}
}
}
Any suggestions on what the issue may be?
I think I found the fix!
I adjusted the layout of my scaffoled in my ToolSetListScreen:
Scaffold (
content = {
SearchBar(
modifier = Modifier,
)
LazyColumn(
modifier = Modifier.fillMaxSize()
.padding(0.dp, 75.dp)
) {
items(toolSets.value) { toolset ->
ToolSetItem(
toolSet = toolset,
onEvent = viewModel::onEvent,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable {
viewModel.onEvent(ToolSetListEvent.OnToolSetClick(toolset))
}
)
}
}
},
floatingActionButton = {
FloatingActionButton(onClick = {
viewModel.onEvent(ToolSetListEvent.OnAddToolSetClick)
}) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add")
}
}
)
}
and this seemed to work.
I have created a Pokemon App with Jetpack Compose. I have two screens. One where the names of the pokemon is being displayed, and a second screen where the details of a selected pokemon will be shown. What I want to achieve is passing the name of the pokemon to a url when it's selected, and getting the information on to the second screen.
const val POKE_DETAILS = "api/v2/pokemon/{name}/"
Network File
interface NetworkingService{
#GET(Endpoints.POKE_LIST)
suspend fun getListResponse(
#Query("limit") limit: String = "151"
): Response<GetPokemonListResponse>
#GET(Endpoints.POKE_DETAILS)
suspend fun getDetailsResponse(
#Path("name") name: String
): GetPokemonDetailResponse
}
object PokemonNetworkObject{
val moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
val retroFit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
val networkingServices: NetworkingService by lazy {
retroFit.create(NetworkingService::class.java)
}
val apiClient = ApiClient(networkingServices)
}
Compose Screens
#Preview
#Composable
fun PokemonListPage(pokemonViewModel: PokemonListViewModel = viewModel(), navController: NavController){
val pokeList = pokemonViewModel.pokemonStateData.collectAsState().value
Surface(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(),
) {
Scaffold(topBar =
{
TopAppBar(
backgroundColor = Color.DarkGray,
elevation = 0.dp,
) {
Row(modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
){
Text(
text = "POKEDEX",
fontWeight = FontWeight.Bold,
fontSize = 25.sp,
color = Color.Magenta
)
}
}
}, backgroundColor = Color.DarkGray){
PokemonCards(pokemons = pokeList!!, navController = navController))
}
// PokemonCards(pokemons = pokeList!!)
}
}
#Composable
private fun PokemonCards(pokemons: List<PokeListEntity>, navController: NavController) {
LazyColumn{
items(pokemons){ pokemon ->
PokemonCard(pokemon = pokemon, navController = navController)
}
}
}
#Composable
private fun PokemonCard(pokemon: PokeListEntity, navController: NavController) {
Card(
modifier = Modifier
.width(500.dp)
.requiredHeight(100.dp)
.padding(10.dp),
backgroundColor = Color.Cyan,
shape = RoundedCornerShape(corner = CornerSize(10.dp)),
elevation = 5.dp
) {
Row(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = pokemon.name,
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
Button(
onClick = {
navController.navigate(route = "pokemon_detail_screen/${pokemon.name}")
}) {
Text(text = "INFO")
}
}
}
}
Details Screen
#Preview
#Composable
fun PokemonDetailScreen(
detailViewModel: DetailViewModel = viewModel(),
navController: NavController,
pokemonName: String // This Variable
) {
val details by detailViewModel.detailState.observeAsState()
Surface(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
color = Color.DarkGray
) {
DetailCard(field = details!!)
}
}
#Composable
private fun DetailCard(field: GetPokemonDetailResponse) {
Card(
modifier = Modifier
.requiredHeight(300.dp)
.fillMaxWidth()
.padding(10.dp),
backgroundColor = Color.Cyan,
shape = RoundedCornerShape(corner = CornerSize(15.dp)),
elevation = 10.dp
) {
Column(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.padding(10.dp),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
DetailFields("Name:", field = field.name)
Divider(thickness = 4.dp)
DetailFields("Height:", field = "${field.height}.in")
Divider(thickness = 4.dp)
DetailFields("Weight:", field = "${field.weight}.lbs")
}
}
}
#Composable
private fun DetailFields(title: String, field: String) {
Column() {
Text(
title,
fontSize = 20.sp
)
Text(
field,
fontSize = 30.sp,
fontWeight = FontWeight.Bold
)
}
}
MainActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PokeDexComposeTheme {
Surface(
modifier = Modifier.fillMaxSize()
) {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "pokemon_list_page"
) {
composable("pokemon_list_page") {
PokemonListPage(navController = navController)
}
composable(
"pokemon_detail_screen/{name}",
arguments = listOf(
navArgument("name") {
type = NavType.StringType
}
)
) {
// The navBackStackEntry contains the arguments
val pokemonName = remember {
it.arguments?.getString("name")
}
PokemonDetailScreen(
pokemonName = pokemonName?.lowercase() ?: "",
navController = navController)
}
}
// val pokeListViewModel = viewModel<PokemonListViewModel>()
// PokemonListPage(pokeListViewModel)
}
}
}
}
}
This is still pretty new to me. Any Suggestions are definitely welcomed. Thanks.
Update
I have created a Navigation Component, but i don't know where to pass the pokemonName String value in the Details Screen
*Here is a copy of the project, if you want to test some things out.
https://drive.google.com/drive/folders/1gLH_Q3jYLhn-6ad0LMBeZHb8HyT8FszC?usp=sharing
I am try to learning jetpack compose those days, so I want to learning bottom sheet in jetpack compose, I do it just for one text, but I want to use it for multiple text, I have one example here, but I am not sure how to implement to my project, is there any solution for more than two text button to apply bottom sheet?
#Composable
fun BottomSheetMyScreen() {
val modalBottomSheetState = rememberModalBottomSheetState(initialValue =
ModalBottomSheetValue.Hidden)
val scope = rememberCoroutineScope()
ModalBottomSheetLayout(
sheetContent = {
BottomSheetFirstScreen()
},
sheetState = modalBottomSheetState,
sheetShape = RoundedCornerShape(topStart = 5.dp, topEnd = 5.dp),
sheetBackgroundColor = Color.Red,
) {
Scaffold(
backgroundColor = Color.Red
) {
MyScreen(
scope = scope, state = modalBottomSheetState
)}}}
#Composable
fun MyScreen(
scope: CoroutineScope, state: ModalBottomSheetState,
) {
MainRow(
name = "name1",
onClick = { scope.launch {
state.show()
}}
)
MainRow(
name = "name2",
onClick = { scope.launch {
state.show()
} }
)}}
#Composable
fun MainRow(
name: String,
onClick: () -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
.clickable(onClick = onClick),
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.width(150.dp)
) {
Text(
text = name,
)}}}
I edit Your Code, you can use this code:
#OptIn(ExperimentalMaterialApi::class)
#Composable
fun BottomSheetMyScreen() {
val modalBottomSheetState = rememberModalBottomSheetState(
initialValue =
ModalBottomSheetValue.Hidden
)
val scope = rememberCoroutineScope()
val sheetContentState = remember {
mutableStateOf(0)
}
ModalBottomSheetLayout(
sheetContent = {
when (sheetContentState.value) {
0 -> {
BottomSheetFirstScreen()
}
1 -> {
BottomSheetSecondScreen()
}
}
},
sheetState = modalBottomSheetState,
sheetShape = RoundedCornerShape(topStart = 5.dp, topEnd = 5.dp),
sheetBackgroundColor = Color.Red,
) {
Scaffold(
backgroundColor = Color.Red
) {
MyScreen(
scope = scope, state = modalBottomSheetState, sheetContentState = sheetContentState
)
}
}
}
Main Row
#Composable
fun MainRow(
name: String,
onClick: () -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = name,
modifier = Modifier.clickable { onClick.invoke() }
)
}
}
And MyScreen
#OptIn(ExperimentalMaterialApi::class)
#Composable
fun MyScreen(
scope: CoroutineScope,
state: ModalBottomSheetState,
sheetContentState: MutableState<Int>
) {
Column(modifier = Modifier.fillMaxWidth()) {
MainRow(
name = "name 1",
onClick = {
scope.launch {
sheetContentState.value = 0
state.show()
}
}
)
MainRow(
name = "name 2",
onClick = {
scope.launch {
sheetContentState.value = 1
state.show()
}
}
)
}
}