Search code examples
android-jetpack-compose-material3kotlin-stateflow

How to use material 3 (1.2.1) and asFlow?


I made some changes to Skizo-ozᴉʞS ツ variant and now it works fine:

private val eventsChannel = MutableSharedFlow<Event>(
    replay = 1, extraBufferCapacity = 64,
    onBufferOverflow = BufferOverflow.DROP_OLDEST

)

and sendEvent function:

fun sendEvent(event: Event) {
    eventBusScope.launch {
        eventsChannel.emit(event)
    }
}

I need to upgrade material 3 from 1.1.2 to 1.2.1, but if I do so, I get error concerning asFlow() -

Using 'asFlow(): Flow<T>' is an error. 'BroadcastChannel' is obsolete and all corresponding operators are deprecated in the favour of StateFlow and SharedFlow

Is there any possibility to use material 3 1.2.1 and asFlow together?

I tried upgrading but I get compilation error.

The code as follows:

object EventBus {

@OptIn(ObsoleteCoroutinesApi::class)
private val eventsChannel = ConflatedBroadcastChannel<Event>()
private val screenState = MutableStateFlow(ContentType.EMPTY)
private val screenOperatorState = MutableStateFlow(OperatorContentType.EMPTY)

@OptIn(ObsoleteCoroutinesApi::class)
val eventFlow: Flow<Event>
    get() = eventsChannel.asFlow()

val getScreen: Flow<ContentType>
    get() = screenState

val getOperatorScreen: Flow<OperatorContentType>
    get() = screenOperatorState

@OptIn(ObsoleteCoroutinesApi::class)
fun sendEvent(event: Event) {
    Log.d("MyLogBackArrow","sendEvent in EventBus $event")
    eventsChannel.trySend(event).isSuccess
}

fun <C>setScreen(screenType: C) {
    when(screenType){
        is ContentType -> {
            screenState.value = screenType

        }

        is OperatorContentType -> {
            screenOperatorState.value = screenType
        }
    }
}

}


Solution

  • You should change the code so you use :

    1. asSharedFlow()

    Represents this mutable shared flow as a read-only shared flow. public fun MutableSharedFlow.asSharedFlow(): SharedFlow = ReadonlySharedFlow(this, null)

    1. tryEmitin case you don't have any CoroutineScopebut without the isSuccess
    object EventBus {
    
        private val eventsChannel = MutableSharedFlow<Event>()
        private val screenState = MutableStateFlow(ContentType.EMPTY)
        private val screenOperatorState = MutableStateFlow(OperatorContentType.EMPTY)
    
        val eventFlow: Flow<Event>
            get() = eventsChannel.asSharedFlow()
    
        val getScreen: Flow<ContentType>
            get() = screenState
    
        val getOperatorScreen: Flow<OperatorContentType>
            get() = screenOperatorState
    
        fun sendEvent(event: Event) {
            Log.d("MyLogBackArrow","sendEvent in EventBus $event")
            eventsChannel.tryEmit(event)
        }
    
        fun <C> setScreen(screenType: C) {
            when (screenType) {
                is ContentType -> {
                    screenState.value = screenType
                }
                is OperatorContentType -> {
                    screenOperatorState.value = screenType
                }
            }
        }
    }