簡體   English   中英

如何在 Jetpack Compose 對話框中過濾來自視圖模型的數據?

[英]How to filter data from a viewmodel in a Jetpack Compose dialog?

我有一個主屏幕,我在其中檢索了視圖模型中的列表字符串。 我還有一個打開對話框的按鈕。 在此對話框中,我有一個文本字段供用戶編寫他想要過濾的單詞(土豆名稱字段),以及用於過濾和取消的按鈕。 當用戶單擊按鈕以接受主屏幕上的列表已被過濾時,如何在視圖模型中應用過濾器?

主屏幕:

@Composable
fun PotatosScreen(
    viewModel: PotatosViewModel,
    state: Success<PotatosData>
) {
    val expandedItem = viewModel.expandedCardList.collectAsState()

    Box(
        modifier = Modifier.fillMaxSize()
    ) {

        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .padding(vertical = 8.dp)
        ) {
            items(state.data.potatos) { potato ->
                potatoCard(
                    potato = potato,
                    onCardArrowClick = { viewModel.itemArrowClick(potato.id) },
                    expanded = expandedItem.value.contains(potato.id)
                )
            }
        }
        
        
        var showCustomDialogWithResult by remember { mutableStateOf(true) }
    
        // Text button for open Dialog
        Text(
            text = "Filter",
            modifier = Modifier
                .clickable { 
                    if (showCustomDialogWithResult) {
                        DialogFilter(
                            onDismiss = {
                                showCustomDialogWithResult = !showCustomDialogWithResult
                            },
                            onNegativeClick = {
                                showCustomDialogWithResult = !showCustomDialogWithResult
                            },
                            onPositiveClick = {
                                showCustomDialogWithResult = !showCustomDialogWithResult
                            }
                        )
                    }
                }
        ) 
    }
}

對話:

@Composable
fun DialogFilter(
    onDismiss: () -> Unit,
    onNegativeClick: () -> Unit,
    onPositiveClick: () -> Unit
) {

    var text by remember { mutableStateOf("") }
    
    Dialog(onDismissRequest = onDismiss) {

        Card(
            shape = RoundedCornerShape(10.dp),
            modifier = Modifier.padding(10.dp, 5.dp, 10.dp, 10.dp),
            elevation = 8.dp
        ) {

            Column(
                Modifier.background(Color.White)
            ) {

                Text(
                    text = stringResource("Filter")
                )
                        
                TextField(
                    value = text
                )
                        
                TextButton(onClick = onNegativeClick) {
                    Text(
                        text = "Cancel                      
                    )
                }
                // How apply filter in viewModel here?
                TextButton(onClick = onPositiveClick) {
                    Text(
                        text = "Filter"
                    )
                }
            }
        }
    }
}

視圖模型:

@HiltViewModel
class PotatosViewModel @Inject constructor(
    private val getPotatosDataUseCase: GetPotatosData
) : ViewModel() {

    private val _state = mutableStateOf<Response<PotatosData>>(Loading)
    val state: State<Response<PotatosData>> = _state

    private val _expandedItemList = MutableStateFlow(listOf<Int>())
    val expandedCardList: StateFlow<List<Int>> get() = _expandedItemList

    private val _isRefreshing = MutableStateFlow(false)

    val isRefreshing: StateFlow<Boolean>
        get() = _isRefreshing.asStateFlow()

    init {
        getPotatos()
    }

    fun refresh() {
        viewModelScope.launch {
            _isRefreshing.emit(true)
            getPotatos()
            _isRefreshing.emit(false)
        }
    }

    private fun getPotatos() {
        viewModelScope.launch {

            getPotatosDataUseCase().collect { response ->
                _state.value = response
            }
        }
    }

    fun containsItem(potatoId: Int): Boolean {

        return _expandedItemList.value.toMutableList().contains(potatoId)
    }

    fun itemArrowClick(potatoId: Int) {

        _expandedItemList.value = _expandedItemList.value.toMutableList().also { list ->
            if (list.contains(potatoId)) {
                list.remove(potatoId)
            } else {
                list.add(potatoId)
            }
        }
    }
}

State:

data class PotatosState(
    val potatoes: List<Potato>,
)

土豆:

data class Potato(
    val id: Int,
    val name: String)

您可以更改onPositiveClick回調以接受String並將其傳遞給ViewModel以應用您的過濾器,如下所示:

fun DialogFilter(
    onDismiss: () -> Unit,
    onNegativeClick: () -> Unit,
    onPositiveClick: (String) -> Unit
)

然后回調將使用文本調用您的 ViewModel

onPositiveClick = { filter ->
    showCustomDialogWithResult = !showCustomDialogWithResult
    viewModel.applyFilter(filter)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM