Код: Выделить всё
@Composable
fun ScreenOne(onClick : (Int) -> Unit){
val number = 34
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = { onClick(number) }) {
Text(text = "Navigate")
}
}
}
Код: Выделить всё
@Composable
fun ScreenTwo(number:Int){
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Got number : $number")
}
}
Код: Выделить всё
@Composable
fun MyApp(modifier: Modifier = Modifier){
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "a"){
composable("a") {
ScreenOne {
num->
navController.navigate("b/${num}")
}
}
composable("b/{num}") {
navBackStackEntry ->
val number = navBackStackEntry.arguments?.getString("num")?.toIntOrNull() ?: 0
ScreenTwo(number = number)
}
}
}
Код: Выделить всё
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
PracticingNavigationTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
MyApp(Modifier.padding(innerPadding))
}
}
}
}
}
Я поделюсь файлами кода основного проекта
p>
- Экран профиля (Экран, с которого я делился идентификатором) ->
Код: Выделить всё
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProfileScreen(
onFabClicked : () -> Unit,
onMailClicked: (Int) -> Unit,
profileScreenViewModel: ProfileScreenViewModel
) {
val TAG = "ProfileScreen"
val mailList by profileScreenViewModel.mailLayoutList.observeAsState(emptyList())
Log.d(TAG,"Size is : ${mailList.size}")
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
val bottomSheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = false
)
var showSheet by remember {
mutableStateOf(false)
}
//Track if FAB is extended
var isExtended by remember {
mutableStateOf(false)
}
Box (
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
detectVerticalDragGestures { _, dragAmount ->
//Detect swipe up or down
if (dragAmount < 0) {
//Swiped Up
isExtended = true
} else if (dragAmount > 0) {
// Swiped down
isExtended = false
}
}
}
) {
ModalNavigationDrawer(
drawerState = drawerState, // Use ModalDrawer's state
drawerContent = {
DrawerItemUiLayout() // Drawer content
},
gesturesEnabled = true, // Allow gestures to open/close the drawer
scrimColor = Color.Black.copy(alpha = 0.32f) // Scrim with dimming effect
) {
Scaffold(
modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars),
topBar = {
TopBarOne(
openDrawer = {
scope.launch {
drawerState.open() // Open drawer with built-in animation
}
},
openProfile = {
showSheet = true
}
)
},
bottomBar = {
BottomBarLayout()
},
floatingActionButton = {
if (isExtended) {
Log.d("FAB","value is : $isExtended")
ExtendedFloatingActionButton(
onClick = { onFabClicked() },
modifier = Modifier.background(Color.Cyan)
) {
Icon(imageVector = Icons.Default.Create, contentDescription = null)
Text(text = "Compose")
}
} else {
Log.d("FAB","value is : $isExtended")
FloatingActionButton(onClick = { onFabClicked() }) {
Icon(imageVector = Icons.Default.Create, contentDescription = null)
}
}
}
) { innerPadding ->
if (showSheet){
ModalBottomSheet(
modifier = Modifier.fillMaxHeight(),
sheetState = bottomSheetState,
onDismissRequest = { showSheet = false }
) {
Text(
"Swipe up to open sheet. Swipe down to dismiss.",
modifier = Modifier.padding(16.dp)
)
}
}
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
// Main content here
items(mailList){
mails ->
MailLayout(
mailLayoutItem = mails,
onMailClicked = {
onMailClicked(it)
Log.d(TAG, "Navigating to ShowMailScreen with id: ${it}")
},
profileScreenViewModel = profileScreenViewModel
)
}
}
}
}
}
}
- ShowMailScreen (THIS получит идентификатор)->
Код: Выделить всё
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ShowMailScreen(
onBackButtonClicked: () -> Unit,
onUnreadMailClicked: () -> Unit,
profileScreenViewModel: ProfileScreenViewModel,
mailId: Int
) {
val TAG = "SHOW_MAIL_SCREEN"
Log.d(TAG, "Got mail with id: ${mailId}")
var mail : MailLayoutItem = MailLayoutItem(
icon = 0,
sender = "null",
receiver = "null",
subject = "null",
content = "null",
time = "00:00",
isFavoriteClicked = false
)
LaunchedEffect(mailId) {
mail = profileScreenViewModel.findAParticularMail(mailId)
}
var isStarClicked by remember { mutableStateOf(mail.isFavoriteClicked) }
val example = listOf("1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1")
Scaffold(
topBar = {
TopBarThree(
onBackButtonClicked = { onBackButtonClicked() },
onMoreButtonClicked = { /*TODO*/ },
onArchiveClicked = { /*TODO*/ },
onDeleteClicked = { /*TODO*/ },
onUnreadMailClicked = { onUnreadMailClicked() }
)
},
bottomBar = { BottomBarLayout()}
) { innerPadding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
// LazyColumn taking 3/4th of the screen
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(3f)
) {
item {
Text(text = "GOt mail with name ${mail.subject}")
}
item {
Row (
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween
){
Text(text = "Your ebook bargains for Tuesday.", fontSize = 26.sp, modifier = Modifier.weight(3f))
IconButton(onClick = {
profileScreenViewModel.ToggleFavorite(mailId = mail.id)
isStarClicked = !isStarClicked
}) {
if (isStarClicked){
Icon(
imageVector = Icons.Filled.Star,
contentDescription = null,
tint = Color.Blue
)
}else{
Icon(painter = painterResource(id = R.drawable.baseline_star_border_24) , contentDescription = null )
}
}
}
}
items(example) { item: String ->
Text(text = item)
}
stickyHeader {
Text(text = "This is the second part", fontWeight = FontWeight.Bold)
}
}
ReplyRowLayout()
}
}
}
- Навигация по приложениям
Код: Выделить всё
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun AppNavigation(profileScreenViewModel: ProfileScreenViewModel = viewModel(
)){
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Screens.PrimaryScreen.route){
composable(route = Screens.PrimaryScreen.route){
ProfileScreen(
onFabClicked = { navController.navigate(Screens.ComposeScreen.route) },
onMailClicked = {
mailId->
navController.navigate("${Screens.ShowMailScreen.route}/{mailId}")
},
profileScreenViewModel = profileScreenViewModel
)
}
composable(route = Screens.ComposeScreen.route) {
ComposeScreen(
onBackButtonClicked = {navController.navigateUp()},
onSendButtonClicked = {navController.navigateUp()},
profileScreenViewModel = profileScreenViewModel
)
}
composable(
route = "${Screens.ShowMailScreen.route}/{mailId}"
) {navBackStackEntry->
val mailId = navBackStackEntry.arguments?.getString("mailId")?.toIntOrNull() ?: 0
ShowMailScreen(
onBackButtonClicked = {navController.navigateUp()},
onUnreadMailClicked = {navController.navigateUp()},
profileScreenViewModel = profileScreenViewModel,
mailId = mailId
)
}
}
}
- ViewModel ->
Код: Выделить всё
class ProfileScreenViewModel(
private val allMailsRepository: MailItemRepository = MailItemGraph.allMailsRepository
) : ViewModel() {
private val TAG = "ProfileScreenViewModel"
private val getDateAndTime = GetDateAndTime()
private val _mailLayoutList = MutableLiveData[*]>(
emptyList()
)
val mailLayoutList: LiveData get() = _mailLayoutList
init {
viewModelScope.launch {
allMailsRepository.getAllMails().collect { mails ->
_mailLayoutList.value = mails.sortedByDescending { it.id }
}
}
}
//Selecting favorite or not Favorite
fun ToggleFavorite(mailId: Int) {
_mailLayoutList.value = _mailLayoutList.value?.map { mailLayoutItem: MailLayoutItem ->
if (mailLayoutItem.id == mailId) {
val updatedMailLayoutItem = mailLayoutItem.copy(
isFavoriteClicked = !mailLayoutItem.isFavoriteClicked
)
viewModelScope.launch {
try {
allMailsRepository.insertMail(updatedMailLayoutItem)
} catch (e: Exception) {
Log.d(TAG, "Can't update the mail : ${e.message}")
}
}
updatedMailLayoutItem
} else {
mailLayoutItem
}
}
}
//Sending the clicked mail to other screen to view full mail
fun findAParticularMail(mailId: Int): MailLayoutItem {
var foundMail: MailLayoutItem = MailLayoutItem(
icon = 0,
sender = "null",
receiver = "null",
subject = "null",
content = "null",
time = "00:00",
isFavoriteClicked = false
)
viewModelScope.launch {
try {
allMailsRepository.getSpecificMail(mailId).collect {
foundMail = it
}
} catch (e: Exception) {
Log.d(TAG, "Specific mail can't be found with error : ${e.message}")
}
}
// val mail = _mailLayoutList.value?.find {
// foundMail->
// foundMail.id == mailId
// }
return foundMail
}
//Adding new mail in list
@RequiresApi(Build.VERSION_CODES.O)
fun addNewMail(mailLayoutItem: MailLayoutItem) {
val currentDateAndTime = LocalDateTime.now(ZoneId.of("Asia/Kolkata"))
val formattedTimeOrDate = getDateAndTime.getFormatedTimeOrDate(currentDateAndTime)
val newMailLayoutItem = mailLayoutItem.copy(time = formattedTimeOrDate)
viewModelScope.launch {
try {
allMailsRepository.insertMail(newMailLayoutItem)
} catch (e: Exception) {
Log.d(TAG, "Error occurred while inserting the mail: ${e.message}")
}
}
}
}
- MailLayout (компонуемый элемент, важный для отправки идентификатора и использования на экране профиля)->
Код: Выделить всё
@Composable fun MailLayout( mailLayoutItem: MailLayoutItem, onMailClicked: (Int) -> Unit, profileScreenViewModel: ProfileScreenViewModel ){ val TAG = "MAIL_LAYOUT_SCREEN" fun truncateString(input:String, maxLength:Int):String{ if (input.length > maxLength){ return input.take(maxLength) + "..." }else{ return input } } val mailImageBitmap = ImageBitmap.imageResource(id = mailLayoutItem.icon) Row ( modifier = Modifier .fillMaxWidth() .padding(8.dp) .clickable { onMailClicked( mailLayoutItem.id ) Log.d(TAG, "Navigating to ShowMailScreen with id: ${mailLayoutItem.id}") }, horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically ){ Box(modifier = Modifier .size(60.dp) .clip(CircleShape) ){ Image(bitmap = mailImageBitmap, contentDescription = null, contentScale = ContentScale.Fit) } Column( modifier = Modifier.fillMaxHeight().padding(horizontal = 8.dp).weight(5f), ) { Text(text = truncateString(mailLayoutItem.sender, 25), fontWeight = FontWeight.Bold) Text(text = truncateString(mailLayoutItem.subject, 50), fontSize = 12.sp, fontWeight = FontWeight.Bold) Text(text = truncateString(mailLayoutItem.content, 40), fontSize = 12.sp) } Column( modifier = Modifier.fillMaxHeight(), verticalArrangement = Arrangement.SpaceBetween ) { Text(text = mailLayoutItem.time, fontSize = 10.sp, fontWeight = FontWeight.ExtraBold) IconButton(onClick = { profileScreenViewModel.ToggleFavorite(mailId = mailLayoutItem.id) }) { if (mailLayoutItem.isFavoriteClicked){ Icon(imageVector = Icons.Filled.Star, contentDescription = null, tint = Color.Blue) }else{ Icon(painter = painterResource(id = R.drawable.baseline_star_border_24), contentDescription = null) } } } } } - Класс данных
Код: Выделить всё
@Entity
data class MailLayoutItem(
@PrimaryKey(autoGenerate = true)
val id : Int = 0,
val icon : Int,
val sender : String,
val receiver : String,
val subject : String,
val content : String,
val time : String,
val isFavoriteClicked : Boolean
)
"
- 2024-09-22 11:11:57.657 12290-12290 ProfileScreen com.example.gmailappclone D Переход к ShowMailScreen с идентификатором: 2
- 2024-09-22 11:11:57.658 12290-12290 MAIL_LAYOUT_SCREEN com.example.gmailappclone D Переход к ShowMailScreen с идентификатором: 2
- 2024-09-22 11:11:57.703 12290-12290 SHOW_MAIL_SCREEN com.example.gmailappclone D Получено письмо с идентификатором: 0
Смиренно прошу вас помочь мне разобраться, почему в моем проекте не работает логика навигации.>
Подробнее здесь: https://stackoverflow.com/questions/790 ... n-to-other