我正在按照 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)
}
}