I want to implement an AnimatedContent in Compose that shows some data from an api that can return null values. When i used ViewFlipper (in Android Views Xml), i could implememnt a code that reads the state flow from a viewmodel and by observing the flow i could change the view type and pass the data. When using animated conetnt in compose with val nowplaying by viewModel. uiNowPlaying. collectAsStateWithLifecycle() as its state, when the response is a Success and it passes the data, it crashes in the AnimatedContent Line due to a nullable item (PreviewUrl in this case) in the data class of the data (which is expected behaviour, the null):

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
at andr.mobile.mustats.domain.model.Track.hashCode(AccessToken.kt:0)
at andr.mobile.mustats.domain.model.NowPlaying.hashCode(AccessToken.kt:0)
at andr.mobile.mustats.utility.NowPlayingCustomUiState$Success.hashCode(UiStates.kt:0)
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.containsKey(HashMap.java:595)
at androidx.compose.animation.AnimatedContentKt.AnimatedContent(AnimatedContent.kt:737)
at androidx.compose.animation.AnimatedContentKt.AnimatedContent(AnimatedContent.kt:142)รง
at andr.mobile.mustats.ui.home.HomeScreenKt$HomeScreen$7$2$2.invoke(HomeScreen.kt:210)
at andr.mobile.mustats.ui.home.HomeScreenKt$HomeScreen$7$2$2.invoke(HomeScreen.kt:209)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:117)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke
......

This is my Data Class

@Parcelize
data class Track (

    @SerializedName("album") var album: AlbumSimple ,
    @SerializedName("artists") var artists : ArrayList<ArtistSimple>,
    @SerializedName("available_markets") var availableMarkets : ArrayList<String> ,
    @SerializedName("disc_number") var discNumber : Int            ,
    @SerializedName("duration_ms") var durationMs  : Int       ,
    @SerializedName("explicit") var explicit : Boolean        ,
    @SerializedName("external_ids") var externalIds: Map<String, String>     ,
    @SerializedName("external_urls") var externalUrls:Map<String, String> ,
    @SerializedName("href") var href: String         ,
    @SerializedName("id") var id : String  ,
    @SerializedName("is_local") var isLocal : Boolean  ,
    @SerializedName("name") var name : String ,
    @SerializedName("popularity") var popularity : Int     ,
    @SerializedName("preview_url") var previewUrl: String?,
    @SerializedName("track_number") var trackNumber : Int  ,
    @SerializedName("type") var type : String,
    @SerializedName("uri") var uri : String
): Parcelable

This is my ui state whic accepts any kind of Data Class as Success

sealed class NowPlayingCustomUiState<out T> {
    object Loading : NowPlayingCustomUiState<Nothing>()

    object NoContent : NowPlayingCustomUiState<Nothing>()

    data class Success<T>(val data: T, val history: Boolean) : NowPlayingCustomUiState<T>()

    data class Error(@StringRes val message: Int) : NowPlayingCustomUiState<Nothing>()

    object NetworkException : NowPlayingCustomUiState<Nothing>()
}

This is what i want to implement

val nowplaying by viewModel. uiNowPlaying. collectAsStateWithLifecycle()
 AnimatedContent(
                    modifier = Modifier,
                    targetState = nowplaying,
                    label = "users animated content"
                ) { state ->
                    when (state) {

                        is NowPlayingCustomUiState.Success -> PlayingInfo(state.data, state.history)
                        else -> {}
                    }
                }

This is happening due to the animated content because i had no previous problemns in Xml android. Is there a workaround so that animated content accepts Dataclasses with nullables items in it?

0

There are 0 answers