Home > Blockchain >  Why is data being shown when screen rotates in jetpack compose
Why is data being shown when screen rotates in jetpack compose

Time:04-03

I'm facing this issue where the data I'm retrieving from an API, https://randomuser.me/api/ at first compose it doesn't load.
But every time I rotate the screen the data updates.

First load
First load

After screen rotation
After screen rotation

View

class MainActivity : ComponentActivity() {
    private val userViewModel : UserViewModel by viewModels()
    private var userList: List<UserModel> = listOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        userViewModel.userModel.observe(this, Observer {
            userList = it
        })
        userViewModel.onCreate()
        setContent {
            ListUsers(userList = userList)
        }
    }
}

ViewModel

class UserViewModel : ViewModel() {
    val userModel = MutableLiveData<List<UserModel>>()
    var getRandomUsersUseCase = RandomUsersUseCase()

    fun onCreate() {
        viewModelScope.launch {
            val result = getRandomUsersUseCase()
            if(!result.isNullOrEmpty()){
                userModel.postValue(result)
            }
        }
    }
}

CodePudding user response:

Use State to ensure the data changes trigger recomposition of the Composable.

If you use another observable type such as LiveData in Compose, you should convert it to State before reading it in a composable using a composable extension function like LiveData.observeAsState().

Changes to your code would be,

val userListState by userViewModel.userModel.observeAsState()

setContent {
    ListUsers(userList = userListState)
}

Why does it shows the data during rotation?

When rotating the screen or during any other configuration changes, the activity will be recreated.

More info on that here - Docs

In most cases, you would not require data to be changed when the screen rotates.

If you want to persist the data even after screen rotation, move the code inside onCreate() in your UserViewModel to the init block, like this.

init {
    getData()
}

fun getData() {
    viewModelScope.launch {
        val result = getRandomUsersUseCase()
        if(!result.isNullOrEmpty()){
            userModel.postValue(result)
        }

    }
}

If you need to refresh the data on any other event like button click, swipe to refresh, etc, just call the getData() again on the event handler.

P.S: Check correct imports are added as required.

import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
  • Related