【问题标题】:Getting the ViewModel in to display information in Jetpack Compose让 ViewModel 在 Jetpack Compose 中显示信息
【发布时间】:2022-11-04 21:44:23
【问题描述】:

因此,我对如何创建 ViewModel 并将其传递到我的可组合项中有些困惑,以便我可以使用数据类模型在 textView 上显示。

这是代码

主要活动

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
        )

    }
}

视图模型

class PokemonListViewModel: ViewModel() {
    private val repository = PokemonRepository(PokemonApplication.pokemonListDatabase.pokemonDao)




init {
    fetchPokemonNames()
}


    private fun fetchPokemonNames(){
        viewModelScope.launch {
            val fetchPokeListEntity = repository.getAllPokemonNames()
                pokemon.value = fetchPokeListEntity
        }
    }


}

我对 Jetpack Compose 还是很陌生,所以我的想法是应用 viewModel 的方式与使用常规 XML 布局的方式相同。任何帮助将不胜感激。

【问题讨论】:

  • 具体是什么不工作?
  • 我似乎无法将 viewModel 连接到 Composable,以便我可以访问 Data Class 并填充 TextView。

标签: android kotlin android-jetpack-compose android-viewmodel


【解决方案1】:

于是就选了一些Udemy上的课程,StateFlow就是用来代替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
        }
    }


} 

我所要做的就是使用 StateFlow 并在 Composeable 中正确设置 ViewModel。它最终完美地工作。

@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 
        }

【讨论】:

  • 你好,我在这里面临同样的问题。你如何将视图模型信息传递给撰写?你能分享一下吗
  • 这么晚才回复很抱歉。有两种方法可以解决这个问题。要么使用 LiveData 并上传依赖项以允许在 Compose 中使用 LiveData,要么使用 StateFlow(强烈推荐)。 StateFlowLiveData 的更好版本,实际上是为 Compose 设计的。只需像使用LiveData 一样设置StateFlow,然后在使用viewModel 的组合上,将viewmodel 作为参数并将其设置为变量。然后使用该变量并将其连接到您需要连接它的位置。我会留下一些 Main Composable 的代码,让你看看它是如何工作的
猜你喜欢
  • 1970-01-01
  • 2022-08-13
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多