So I am a bit stuck with how to create the ViewModel and pass it into my composable so that I can use the Data Class models to display on the textView.
Here's the code
MainActivity
private const val TAG = "MainActivity"
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: PokemonListViewModel by viewModels()
setContent {
// val pokemon = viewModel.pokemon.value
PokeDexComposeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = Color.Cyan) {
PokemonListScreen()
}
}
}
}
}
@Composable
fun PokemonListScreen(viewModel: PokemonListViewModel){
//Tried this method as well
val pokemon by viewModel.pokemonLiveData.observeAsState("")
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
) {
ClickableText(
text = AnnotatedString(),
onClick = {offset ->
Log.d(TAG, "PokemonListScreen: clicked")
},
)
Divider(
Modifier.padding(start = 24.dp, end = 24.dp),
color = Color.Black,
thickness = 2.dp
)
}
}
@Composable
fun PokemonDetails(){
Column(
modifier = Modifier
.fillMaxSize()
.padding(top = 16.dp),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
fontSize = 25.sp,
text = "NAME: "
)
Text(
fontSize = 50.sp,
text = "NameModel"
)
Divider(
modifier = Modifier.padding(start = 24.dp, end = 24.dp),
color = Color.Black,
thickness = 1.dp
)
Text(
modifier = Modifier.padding(8.dp),
fontSize = 25.sp,
text = "HEIGHT: "
)
Text(
fontSize = 50.sp,
text = "HeightModel"
)
Divider(
modifier = Modifier.padding(start = 24.dp, end = 24.dp),
color = Color.Black,
thickness = 1.dp
)
Text(
modifier = Modifier.padding(8.dp),
fontSize = 25.sp,
text = "WEIGHT: "
)
Text(
fontSize = 50.sp,
text = "WeightModel"
)
Divider(
modifier = Modifier.padding(start = 24.dp, end = 24.dp),
color = Color.Black,
thickness = 1.dp
)
}
}
ViewModel
class PokemonListViewModel: ViewModel() {
private val repository = PokemonRepository(PokemonApplication.pokemonListDatabase.pokemonDao)
init {
fetchPokemonNames()
}
private fun fetchPokemonNames(){
viewModelScope.launch {
val fetchPokeListEntity = repository.getAllPokemonNames()
pokemon.value = fetchPokeListEntity
}
}
}
I am pretty new to Jetpack Compose, so my mindset was applying the viewModels the same way I would with regular XML layouts. Any help will be appreciated.
So I picked up some courses on Udemy, and StateFlow was the method used to replace MutableLiveData.
class PokemonListViewModel: ViewModel() {
private val repository = PokemonRepository(PokemonApplication.pokemonListDatabase.pokemonDao)
private val _pokemonStateData = MutableStateFlow<List<PokeListEntity>?>(emptyList())
val pokemonStateData = _pokemonStateData.asStateFlow()
init {
fetchPokemonNames()
}
fun fetchPokemonNames(){
viewModelScope.launch {
val fetchPokeListEntity = repository.getAllPokemonNames()
_pokemonStateData.value = fetchPokeListEntity
}
}
}
All I had to do was to use StateFlow and set up the ViewModel inside the Composeable properly. And it ended up working perfectly.
@Composable
fun PokemonListPage(
pokemonViewModel: PokemonListViewModel = viewModel(), //<- adding viewModel as a parameter
navController: NavController){
val pokeList = pokemonViewModel.pokemonStateData.collectAsState().value //<- creating a variable for the StateFlow variable
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) //<- setting that variable to another composable which is leveraging the info from the viewModel
}