0

我正在按照 Mitch Tabian 关于 Jetpack Compose 的 youtube 教程构建一个简单的应用程序。在 State Hoisting 视频中,他将搜索 TextField 的代码提取到单独的 Composable 中。当我这样做时,我的 textField 不会更新值,我找不到我做错了什么。

SearchAppBar 可组合

@Composable
fun SearchAppBar(
  query: String,
  onQueryChanged: (String) -> Unit,
  onExecuteSearch: () -> Unit,
  selectedCategory: FoodCategory?,
  onSelectedCategoryChanged: (String) -> Unit
) {
  Surface(
    modifier = Modifier
      .fillMaxWidth(),
    color = Color.White,
    elevation = 4.dp
  ) {
    Column {
      Row(modifier = Modifier.fillMaxWidth()) {
        val focusManager = LocalFocusManager.current
        OutlinedTextField(
          value = query,
          onValueChange = { newValue -> onQueryChanged(newValue) },
          modifier = Modifier
            .background(color = MaterialTheme.colors.surface)
            .fillMaxWidth()
            .padding(8.dp),
          label = {
            Text(text = "Search")
          },
...

分段

class RecipeListFragment : Fragment() {
  private val viewModel: RecipeListViewModel by viewModels()

  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    return ComposeView(requireContext()).apply {
      setContent {
        val recipes = viewModel.recipes.value
        val query = viewModel.query.value
        val selectedCategory = viewModel.selectedCategory.value
        Column {
          SearchAppBar(
            query = query,
            onQueryChanged = { viewModel.onQueryChanged(query) },
            onExecuteSearch = { viewModel::newSearch },
            selectedCategory = selectedCategory,
            onSelectedCategoryChanged = { viewModel::onSelectedCategoryChanged })
          LazyColumn {
            itemsIndexed(items = recipes) { index, recipe ->
              RecipeCard(recipe = recipe, onClick = { })
            }
          }
        }
      }
    }
  }
}

视图模型

class RecipeListViewModel @Inject constructor(private val repository: RecipeRepository, @Named("auth_token") private val token: String) : ViewModel() {
  val recipes: MutableState<List<Recipe>> = mutableStateOf(listOf())
  val query = mutableStateOf("")
  val selectedCategory: MutableState<FoodCategory?> = mutableStateOf(null)

  init {
    newSearch()
  }

  fun onQueryChanged(query: String) {
    this.query.value = query
  }

  fun newSearch() {
    viewModelScope.launch {
      recipes.value = repository.search(token = token, page = 1, query = query.value)
    }
  }

  fun onSelectedCategoryChanged(category: String) {
    val newCategory = getFoodCategory(category)
    selectedCategory.value = newCategory
    onQueryChanged(category)
  }
}
4

1 回答 1

0

以下不再是观察到的状态。

val recipes = viewModel.recipes.value
val query = viewModel.query.value
val selectedCategory = viewModel.selectedCategory.value

延迟.value调用或使用var by viewModel.recipes或使用重组val (recipes, _) = viewModel.recipes

于 2021-02-28T11:15:19.320 回答