Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigating is losing Screen state #318

Open
JagadishaIncture opened this issue May 9, 2024 · 8 comments
Open

Navigating is losing Screen state #318

JagadishaIncture opened this issue May 9, 2024 · 8 comments

Comments

@JagadishaIncture
Copy link

Describe the bug
When we navigate from Screen A to Screen B and coming back to Screen A which leads to recreate screen A . means screen start recreates and re hits api call and fetches data

Expected behavior
Screen A state should be retained

@Tlaster
Copy link
Owner

Tlaster commented May 9, 2024

Hi can you provide some sample code that reproduce this issue?

@JagadishaIncture
Copy link
Author

Screen A

` @composable
fun GroupsScreen(
viewModel: GroupViewModel,
baseViewModel: BaseViewModel,
platformUtils: PlatformUtils,
navigator: Navigator,
localSharedStorage: LocalSharedStorage,
showToolBar:Boolean=false
) {

var isLoading by remember { mutableStateOf(false) }
var isShimming by remember { mutableStateOf(false) }
var data: List<GroupsItemModel> by remember { mutableStateOf(ArrayList()) }

var currentPage by remember { mutableStateOf(0) }
val pageCount = 10
val totalRecords = 0

val lazyListState = rememberLazyGridState()

if (isLoading) {
    DialogCustomCircleProgressbar()
}

Scaffold {

        Column(
            modifier = Modifier.fillMaxWidth().fillMaxHeight().padding(top = 5.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            if (showToolBar) {
                ToolBarWithBack(navigator = navigator, stringResource(MR.strings.groups))
            }
            if (isShimming) {
                GroupScreenShimmer(platformUtils)
            }else{
            LazyVerticalGrid(
                columns = GridCells.Fixed(if (platformUtils.isTablet()) 2 else 1),
                state = lazyListState,
                modifier = Modifier.fillMaxHeight(1f).fillMaxWidth()
            ) {
                itemsIndexed(data) { _, item ->
                    Card(
                        shape = RoundedCornerShape(8.dp),
                        modifier = Modifier
                            .padding(8.dp)
                            .fillMaxWidth()
                            .clickable {
                                val id = item.groupId.toString()
                                if(showToolBar){
                                    navigator.navigate(NavigationRoute.GroupsDetailScreen.getRoute(id))
                                }
                                else{
                                    navigator.navigate(NavigationRoute.GroupsDetailScreenAdmin.getRoute(id))
                                }

                            },
                        elevation = 2.dp
                    ) {
                        Row(modifier = Modifier.fillMaxWidth()) {

                            RoundedCornerImageView(platformUtils,item.profileImage,Modifier.fillMaxWidth(0.3f).height(100.dp).padding(5.dp))

                            Column(modifier = Modifier.weight(1f).padding(8.dp), verticalArrangement = Arrangement.Center) {
                                Text(
                                    text = item.name.toString(),
                                    style = StyleUtils.getBoldFontStyle()
                                )
                                Spacer(modifier = Modifier.height(3.dp))
                                Text(
                                    text = item.description.toString(),
                                    maxLines = 1,
                                    style = StyleUtils.getSemiBoldFontStyle(),
                                    overflow = TextOverflow.Ellipsis
                                )
                            }
                            if (showToolBar) {
                                Box(modifier = Modifier.align(Alignment.CenterVertically)) {
                                    Spacer(modifier = Modifier.width(8.dp))
                                    DeleteButton(modifier = Modifier.size(40.dp)) {
                                        baseViewModel.deletePost(
                                            category = Category.GROUP.name,
                                            item.groupId.toString(),
                                            localSharedStorage.getUserId()
                                        )
                                    }
                                }
                            }
                        }
                    }
                }
            }


        }
    }
}




LaunchedEffect(Unit)
{
    viewModel.getGroupPlace(currentPage, pageCount)

    viewModel._uiState.collect {

        when {
            it.isLoading -> {
                if (currentPage==0)
                {
                    isShimming = true
                }else{
                    isLoading =true
                }

            }


            it.error.isNotEmpty() -> {
                isShimming = false
                isLoading =false
                platformUtils.makeToast(it.error)
            }

            it.data != null -> {
                isShimming = false
                isLoading =false
                data = it.data
            }

        }
    }
}

LaunchedEffect(Unit)
{

    baseViewModel._deleteResponse.collect {

        when {
            it.isLoading -> {
                isLoading = true
            }

            it.error.isNotEmpty() -> {
                isLoading = false
                platformUtils.makeToast(it.error)
            }

            it.success != null -> {
                isLoading = false
                platformUtils.makeToast(it.success)
                currentPage=0
                viewModel.getGroupPlace(currentPage, pageCount)
            }

        }
    }
}

LaunchedEffect(lazyListState) {
    snapshotFlow { lazyListState.layoutInfo.visibleItemsInfo.lastOrNull()?.index }
        .collect { lastIndex ->
            if (lastIndex != null && lastIndex >= data.size - 1 && !isLoading) {
                if(data.size < totalRecords){
                    if(platformUtils.isOnline()){
                        currentPage++
                        viewModel.getGroupPlace(currentPage, pageCount)
                    }
                }
            }
        }
}

}`

@JagadishaIncture
Copy link
Author

Screen B

`@OptIn(ExperimentalAdaptiveApi::class)
@composable
fun GroupsDetailScreen(
navigator: Navigator,
viewModel: GroupViewModel,
platformUtils: PlatformUtils,
id: String,
showToolBar: Boolean = false
) {
var isShimming by remember { mutableStateOf(false) }
var data: List by remember { mutableStateOf(emptyList()) }
val lazyListState = rememberLazyGridState()

Scaffold(
    topBar = {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .background(color = ColorResources.ComponentColor),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(modifier = Modifier.weight(.8f)) {
                ToolBarWithBack(
                    navigator = navigator,
                    title = stringResource(MR.strings.concert)
                )
            }
            Column {
                AdaptiveIconButton(onClick = {
                    if (showToolBar) {
                        navigator.navigate(NavigationRoute.UserInGroupScreen.getRoute(id))
                    } else {
                        navigator.navigate(NavigationRoute.UserInGroupScreenAdmin.getRoute(id))
                    }
                }) {
                    Icon(
                        imageVector = Icons.Outlined.Person,
                        contentDescription = null,
                        tint = ColorResources.IconColor
                    )
                }
            }
        }
    }
) {
    if (isShimming) {
        GroupDetailScreenShimmer(platformUtils)
    } else {
        Column {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp, vertical = 8.dp)
            ) {
                if (showToolBar) {
                    Box(
                        modifier = Modifier
                            .background(
                                color = Color.Green,
                                shape = RoundedCornerShape(12.dp)
                            )
                            .padding(horizontal = 8.dp, vertical = 4.dp)
                            .clickable {
                                navigator.navigate(NavigationRoute.SendMessageScreen.getRoute(id))
                            }
                            .align(Alignment.TopEnd)
                    ) {
                        Text(
                            text = stringResource(MR.strings.send),
                            color = Color.White,
                            fontWeight = FontWeight.Bold,
                            modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
                        )
                    }
                }
            }

            LazyVerticalGrid(
                columns = GridCells.Fixed(if (platformUtils.isTablet()) 2 else 1),
                state = lazyListState,
                modifier = Modifier.fillMaxSize().padding(top = 5.dp)
            ) {
                if (data.isEmpty()) {
                    item {
                        NoDataView()
                    }
                } else {
                    itemsIndexed(data) { index, item ->
                        Card(
                            shape = RoundedCornerShape(12.dp),
                            elevation = 8.dp,
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(8.dp)
                        ) {
                            Column(
                                modifier = Modifier.padding(16.dp)
                            ) {
                                Row(verticalAlignment = Alignment.CenterVertically) {
                                    Box(
                                        modifier = Modifier
                                            .size(40.dp)
                                            .background(color = Color.DarkGray, shape = CircleShape),
                                        contentAlignment = Alignment.Center
                                    ) {
                                        Text(
                                            text = item.createdByName?.take(1)?.uppercase() ?: "",
                                            color = Color.White,
                                            fontSize = 20.sp,
                                            fontWeight = FontWeight.Bold
                                        )
                                    }
                                    Spacer(modifier = Modifier.width(8.dp))
                                    Text(
                                        text = item.createdByName ?: "",
                                        style = TextStyle(
                                            fontWeight = FontWeight.Bold,
                                            fontSize = 16.sp
                                        ),
                                        modifier = Modifier.weight(1f)
                                    )
                                }
                                Spacer(modifier = Modifier.height(16.dp))
                                Spacer(modifier = Modifier.weight(1f))
                                Row(
                                    modifier = Modifier.fillMaxWidth(),
                                    horizontalArrangement = Arrangement.SpaceBetween
                                ) {
                                    Text(
                                        text = item.textContent ?: "",
                                        style = TextStyle(
                                            fontWeight = FontWeight.Light,
                                            color = Color.Black
                                        )
                                    )
                                    Text(
                                        text = TimeConversionClass.convertLongToDate(item.createdOn!!.toLong()),
                                        style = TextStyle(
                                            fontWeight = FontWeight.Light,
                                            color = Color.Gray
                                        )
                                    )
                                }
                                Spacer(modifier = Modifier.height(16.dp))
                                RoundedCornerImageView(
                                    platformUtils,
                                    item.imageContent,
                                    Modifier.height(200.dp).padding(6.dp)
                                )
                            }
                        }
                    }
                }
            }
        }
    }

    LaunchedEffect(Unit) {
        viewModel.getGroupsItemDetail(id, getnoOfRecordsPerPage = 4, pageNumber = 0)

        viewModel._uidetailState.collect { uiState ->
            when {
                uiState.isLoading -> {
                    isShimming = true
                }
                uiState.error.isNotEmpty() -> {
                    isShimming = false
                    platformUtils.makeToast(uiState.error)
                }
                uiState.data != null -> {
                    isShimming = false
                    data = uiState.data
                }
            }
        }
    }
}

}`

@JagadishaIncture
Copy link
Author

ToolBar code

@OptIn(ExperimentalAdaptiveApi::class) @Composable fun ToolBarWithBack(navigator: Navigator,title: String) { AdaptiveTopAppBar( title = { Text(title,style = StyleUtils.getBoldFontStyle()) }, navigationIcon = { Image(imageVector = Icons.Default.KeyboardArrowLeft, contentDescription = null, colorFilter = ColorFilter.tint(color = ColorResources.IconColor),modifier = Modifier.clickable { navigator.goBack() }) } ) }

@Tlaster
Copy link
Owner

Tlaster commented May 9, 2024

Seems like you're fetching from LaunchedEffect

LaunchedEffect(Unit)
{
    viewModel.getGroupPlace(currentPage, pageCount)
    //...
}

LaunchedEffect(Unit) will run When LaunchedEffect enters the Composition, in this case, when you're navigating from GroupsScreen to other screen, you GroupsScreen is actually cleared from the composition, so when you're back from other screen to GroupsScreen, the GroupsScreen is entering the composition once again, which triggers LaunchedEffect to run once again.

@JagadishaIncture
Copy link
Author

any solution her how to avoid api call when returning back to GroupsScreen?

@Tlaster
Copy link
Owner

Tlaster commented May 9, 2024

You can place your API call in ViewModel's initializer.

@JagadishaIncture
Copy link
Author

you suggets me here

`class GroupViewModel(private val mainUseCase: MainUseCase) : ViewModel() {

val _uiState = MutableSharedFlow()

fun getGroupPlace(currentPage: Int, pageCount: Int) {

    val groupPayloadModel = CategoryPayloadModel().apply {
        statusList = arrayListOf(Status.ACTIVE.name)
        pageNumber = currentPage
        noOfRecordsPerPage = pageCount
    }

    mainUseCase.getGroups(groupPayloadModel).onEach { res ->
        when (res) {
            is NetworkResult.Loading -> {
                _uiState.emit(GroupStateHolder(isLoading = true))
            }

            is NetworkResult.Success -> {
                data = emptyList()
                data = data + (res.data ?: emptyList())
                _uiState.emit(GroupStateHolder(data = data, totalRecords = res.totalRecords))
            }

            is NetworkResult.Error -> {
                _uiState.emit(GroupStateHolder(error = res.message))
            }
        }
    }.launchIn(viewModelScope)
}

}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants