I'm new and taking the android basics with compose course, and specifically the flight search project https://developer.android.com/codelabs/basic-android-kotlin-compose-flight-search, here you need to add a search for airports from the database. I created a database, made a dao, but I don’t understand why I can’t get a list of airports in this code: MainScreen()
...
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
...
@Composable
fun MainScreen(
modifier: Modifier = Modifier,
viewModel: MainViewModel = viewModel(factory = MainViewModel.factory)
) {
val content = remember { mutableStateListOf<Favorite>() }
val searchText by viewModel.searchText.collectAsState()
val isSearching by viewModel.isSearching.collectAsState()
val airportList by viewModel.airportList.collectAsState(emptyList())
Scaffold(
topBar = {
AppTopBar()
}
) {
Column(
modifier = modifier
.padding(it)
.fillMaxSize()
) {
AppSearchBar(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
searchText = searchText,
isSearching = isSearching,
airportList = airportList,
viewModel = viewModel
)
LazyColumn {
...
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppSearchBar(
modifier: Modifier = Modifier,
searchText: String,
isSearching: Boolean,
airportList: List<Airport>,
viewModel: MainViewModel
) {
SearchBar(
query = searchText,
onQueryChange = viewModel::onSearchTextChange,
onSearch = viewModel::onSearchTextChange,
active = isSearching,
onActiveChange = { viewModel.onToggleSearch() },
placeholder = { Text("Input flight") },
leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
) {
LazyColumn {
items(airportList) { airport ->
Text(
text = airport.name,
modifier = ...
)
}
}
}
}
...
MainViewModel()
class MainViewModel(
private val airportDao: AirportDao, private val favoriteDao: FavoriteDao
) : ViewModel() {
private val _isSearching = MutableStateFlow(false)
val isSearching = _isSearching.asStateFlow()
private val _searchText = MutableStateFlow("")
val searchText = _searchText.asStateFlow()
private val _airportList = MutableStateFlow(emptyFlow<List<Airport>>())
val airportList = _airportList.asStateFlow()
private val _favoriteList = MutableStateFlow(favoriteDao.getFavorites())
val favoriteList = _favoriteList.asStateFlow()
fun onSearchTextChange(text: String) {
_searchText.value = text
_airportList.value = airportDao.getSearchResults(text)
}
fun onToggleSearch() {
_isSearching.value = !_isSearching.value
if (!_isSearching.value) {
onSearchTextChange("")
}
}
companion object {
val factory : ViewModelProvider.Factory = viewModelFactory {
initializer {
val application = (this[APPLICATION_KEY] as FlightSearchApplication)
MainViewModel(application.database.airportDao(), application.database.favoriteDao())
}
}
}
}
in mainscreen() an error is thrown on the line val airportList by viewModel.airportList.collectAsState(emptyList())
I tried to make the same code as in the previous code lab, but I don't understand the concept of flow
private val _airportList = MutableStateFlow*<List<Airport>>(emptyList())*
fun onSearchTextChange(text: String) {
_searchText.value = text
*viewModelScope.launch {
airportDao.getSearchResults(text).collect { searchResults ->
_airportList.value = searchResults
}
}*
}