Невозможно отправить целочисленное значение с одного экрана на другойAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Невозможно отправить целочисленное значение с одного экрана на другой

Сообщение Anonymous »

Я пытаюсь отправить идентификатор одного из моих объектов с одного экрана на другой, но не знаю, почему он не получает правильный идентификатор. Когда я отдельно попытался понять концепцию навигации и создал небольшое приложение, оно заработало. Это маленькое приложение было таким

Код: Выделить всё

@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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»