无法在 ViewModel 中过滤数据 - Android Kotlin

问题描述 投票:0回答:1

从 API 获取数据时,我在过滤 ViewModel 中的数据时遇到问题。我有一个 ViewModel (CharacterViewModel),它使用 getCharactersUseCase 检索数据。我想根据角色 ID 过滤这些数据,并在可组合项 (CharacterDetailScreen) 中观察过滤结果。但是,我没有得到预期的结果。

角色视图模型


  @HiltViewModel
  class CharacterViewModel @Inject constructor(
   private val getCharactersUseCase: GetCharactersUseCase
  ) : ViewModel() {
   private val _characterState: MutableStateFlow<PagingData<Character>> =
       MutableStateFlow(value = PagingData.empty())
   private val _characterDetailsState: MutableStateFlow<Character?> = MutableStateFlow(null)

   val charactersState: MutableStateFlow<PagingData<Character>> get() = _characterState
   val characterDetailsState: MutableStateFlow<Character?> get() = _characterDetailsState

   init {
       getCharacters()
   }

   private fun getCharacters() {
       viewModelScope.launch {
           getCharactersUseCase.execute(Unit)
               .distinctUntilChanged()
               .cachedIn(viewModelScope)
               .collect {
                   _characterState.value = it
               }
       }
   }
   fun getCharacterDetails(characterID: String) {
       Log.i("character"," character from viewmodel received id= ${characterID}")
       // Collect the latest charactersState and then filter the character
       viewModelScope.launch {
           charactersState.collect { characters ->
               characters
                   .filter { it.id == characterID }
                   .map { character ->
                       Log.i("character"," character from viewmodel id= ${character.id}")
                       _characterDetailsState.value = character
                   }
           }
       }
   }
}

角色详情画面


 @Composable
 fun CharacterDetailScreen(
    navController: NavController,
    viewModel: CharacterViewModel = hiltViewModel(),
     characterId: String
 )
 {
    // Collect character details state
    val characterDetailsState by viewModel.characterDetailsState.collectAsState()

    LaunchedEffect(characterDetailsState) {
        viewModel.getCharacterDetails(characterId)
    }
    // Use LaunchedEffect to trigger the getCharacterDetails call when the Composable is first       launched
    CharacterDetailsItem(characterDetailsState, characterId)
    }

角色详情项目

   
    @Composable
    fun CharacterDetailsItem(character_: Character?, characterId: String){
    Log.i("character"," character from details item ${character_?.name}")
    val character by remember { mutableStateOf(character_) }
    Box(modifier = Modifier.padding(top = 8.dp)) {
        Card(
            colors = CardDefaults.cardColors(
                containerColor = MaterialTheme.colorScheme.surfaceVariant,
            ),
            modifier = Modifier
                .fillMaxWidth()

        ) {
            Column {
                Text(
                    text = characterId,
                    modifier = Modifier
                        .padding(16.dp),
                    textAlign = TextAlign.Center,
                )
                character?.name?.let {
                    Text(
                        text = it,
                        modifier = Modifier
                            .padding(16.dp),
                        textAlign = TextAlign.Center,
                    )
                }
                character?.gender?.let {
                    Text(
                        text = it,
                        modifier = Modifier
                            .padding(16.dp),
                        textAlign = TextAlign.Center,
                    )
                }
            }
        }
    }
  }

日志猫

2023-11-17 12:01:19.709  5486-5486  character               com.starwars.app                     I   character from details item null
2023-11-17 12:01:19.740  5486-5486  character               com.starwars.app                     I   character from viewmodel received id= 631a02dc-ecf2-4636-8e59-d180766e52cf
2023-11-17 12:01:19.760  5486-5486  character               com.starwars.app                     I   character from details item null
2023-11-17 12:01:20.472  5486-5486  character               com.starwars.app                     I   character from details item null
2023-11-17 12:01:20.524  5486-5486  character               com.starwars.app                     I   character from details item null

我提供了 ViewModel (CharacterViewModel)、Composable (CharacterDetailScreen) 和用于显示详细信息的 Composable (CharacterDetailsItem) 的代码片段。如果您能深入了解 ViewModel 中的过滤逻辑可能导致的问题,我将不胜感激。

我尝试过的:

    fun getCharacterDetails(characterID: String) {
    Log.i("character", " character from viewmodel received id= ${characterID}")
    // Collect the latest charactersState and then filter the character
    viewModelScope.launch {
     _characterDetailsState.value = Character("213","bday","e","g","h","hi","name","skin")
      
    }
}

这样我就可以设置和获取值,但不能从charactersState或_characterState过滤值中设置和获取值。

android kotlin mvvm viewmodel
1个回答
0
投票

我认为你不应该收集里面的状态

ViewModel
。如果您想通过搜索查询过滤州列表。

您可能需要考虑类似的解决方案:https://stackoverflow.com/a/72311648/7805359

© www.soinside.com 2019 - 2024. All rights reserved.