Как изменить значение Kotlin Coroutine Flow после инициализации? - PullRequest
0 голосов
/ 10 марта 2020

Ожидается

Инициализируйте Kotlin поток сопрограмм и измените его значение после создания потока.

Желаемая функциональность аналогична MutableLiveData setValue, который позволяет добавлять данные в существующий объект MutableLiveData. В приведенном ниже примере setValue вызывается для значения _feed MutableLiveData в FeedViewModel.kt для обновления значения.

Работает как положено, выдает значения в FeedFragment.kt

FeedViewState.kt

data class _FeedViewState(
    val _feed: MutableLiveData<List<Tweet>> = MutableLiveData()
)

data class FeedViewState(private val _feedViewState: _FeedViewState) {
    val feed: LiveData<List<Tweet>> = _feedViewState._feed
}

FeedViewModel.kt

class FeedViewModel(...) : ViewModel() {
    private val _feedViewState = _FeedViewState()
    val feedViewState = FeedViewState(_feedViewState)
    init {
        viewModelScope.launch(Dispatchers.IO) {
            feedRepository.getFeed().collect { results ->
                when (results.status) {
                    LOADING -> ...
                    SUCCESS -> withContext(Dispatchers.Main) {
                        _feedViewState._feed.value = results.data
                    }
                    ERROR -> ...
                }
            }
        }
    }
}

FeedFragment.kt

class FeedFragment : Fragment() {
    override fun onCreateView(...): View? {
        viewModel.feedViewState.feed.observe(viewLifecycleOwner){ feed ->
                //Do something with the tweets here.
        }        
        return inflater.inflate(R.layout.fragment_feed, container, false)
    }
}

Observed

Чтобы реализовать тот же шаблон, используя Kotlin Сопутствующие LiveData в FeedViewState.kt заменены на Flow. В FeedViewModel.kt желаемый результат заключается в добавлении данных к значению _feed Flow. В попытках решения применялись значения map и emit внутри transform и onCompletion к значению _feed Flow.

Однако это решение не генерирует требуемые значения из значения Flow в FeedFragment.kt .

FeedViewState.kt

data class _FeedViewState(
    val _feed: Flow<List<Tweet>> = flow { }
)

data class FeedViewState(private val _feedViewState: _FeedViewState) {
    @ExperimentalCoroutinesApi
    val feed: Flow<List<Tweet>> = _feedViewState._feed }
}

FeedViewModel.kt

class FeedViewModel(...) : ViewModel() {
    private val _feedViewState = _FeedViewState()
    val feedViewState = FeedViewState(_feedViewState)
    init {
        viewModelScope.launch(Dispatchers.IO) {
            feedRepository.getFeed().collect { results ->
                when (results.status) {
                    LOADING -> ...
                    SUCCESS -> withContext(Dispatchers.Main) {
                        _feedViewState._feed.map { results.data!! }
                    }
                    ERROR -> ...
                }
            }
        }
    }
}

FeedFragment.kt

class FeedFragment : Fragment() {
    override fun onCreateView(...): View? {
        lifecycleScope.launch {
            viewModel.feedViewState.feed.collect { tweets ->
                //Do something with the tweets here.
            }
        }
        return inflater.inflate(R.layout.fragment_feed, container, false)
    }
}

1 Ответ

1 голос
/ 10 марта 2020

Поток должен быть автономным . Я хотел бы предложить использовать ConflatedBroadcastChannel , который предлагает функциональность, которую, я полагаю, вы ищете, но в настоящее время это экспериментальная функция в kotlin

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...