在 Android Kotlin 中从 Flow<List<Item>> 中筛选 <Item>

Filtering <Item> from Flow<List<Item>> in Android Kotlin

提问人:sujan_014 提问时间:7/22/2023 更新时间:7/22/2023 访问量:72

问:

我有一个名为 Item 的数据类。在我的视图模型中,我有 Flow<List>它从 Room db 获取项目列表。在此程序中,当用户在 Textfield 中输入某些文本时,将调用 onSearchTextChange。键入一些文本后,我想在UI列表字段中仅显示与输入文本的firstName或middleName或lastName匹配的列表项。我怎样才能做到这一点?

data class Item(
    @PrimaryKey
    val id: Int? = null,
    val firstName: String,
    val middleName: String,
    val lastName: String,
}

class ItemListViewModel @Inject constructor(
    private val repository: ItemRepository
): ViewModel() {

    var itemList: Flow<List<Item>> = repository.getAllItem()
    private val _searchText = MutableStateFlow("")
    val searchText: StateFlow<String> = _searchText.asStateFlow()

    fun onSearchTextChange(text: String){

        _searchText.value = text                
        if (_searchText.value.isNotEmpty() && _searchText.value.isNotBlank()) {                    
            itemList = itemList.onEach { list ->
                list.filter {
                    it.queryName(text)
                }
            }
        } else{
            itemList= repository.getAllItem()
        }
    }
}
Android 列表 android-studio

评论


答:

0赞 ObscureCookie 7/22/2023 #1

您可以使用 .flatMatLatest

class ItemListViewModel @Inject constructor(
    private val repository: ItemRepository
): ViewModel() {
    @OptIn(ExperimentalCoroutinesApi::class)
    val itemList: Flow<List<Item>> = searchText.flatMapConcat { text ->
        if (text.isNotBlank()) {
            repository.getAllItem().onEach { list -> list.filter { /* filter predicate */ } }
        } else {
            repository.getAllItem()
        }
    }

    private val _searchText = MutableStateFlow("")
    val searchText: StateFlow<String> = _searchText.asStateFlow()

    fun onSearchTextChange(text: String){
        _searchText.update { text }
    }
}