Android Safe Args, nav_graph and enums error: Comparison of incompatible enums is always unsuccessful
Asked Answered
D

1

6

I'm experiencing a weird issue here with Safe Args when trying to pass an argument of a type that's an enum defined inside such fragment class. Some code, for clarification.

This is the enum, as it is defined inside the "EvaluationFragment" kotlin class:

    enum class EnrollmentOutcome(vararg labels: String) {
        Accepted("AUTO_APPROVED"), Rejected("AUTO_DECLINED"), Reviewing("REVIEW_REQUIRED"), Unknown(
            "UNAVAILABLE"
        );

        private val outcomeLabels: MutableList<String> = ArrayList()

        companion object {
            fun fromString(label: String): EnrollmentOutcome {
                return when {
                    Accepted.outcomeLabels.contains(label) -> {
                        Accepted
                    }
                    Rejected.outcomeLabels.contains(label) -> {
                        Rejected
                    }
                    Reviewing.outcomeLabels.contains(label) -> {
                        Reviewing
                    }
                    else -> {
                        Unknown
                    }
                }
            }
        }

        init {
            outcomeLabels.addAll(listOf(*labels))
        }
    }

This is the involved fragment entry as defined in nav_graph.xml file:

    <fragment
        android:id="@+id/evaluationFragment"
        android:name="com.whatever.domain.EvaluationFragment"
        android:label="fragment_evaluation"
        tools:layout="@layout/fragment_evaluation" >
        <argument
            android:name="outcome"
            app:argType="com.whatever.domain.EvaluationFragment$EnrollmentOutcome"
            android:defaultValue="Unknown" />
    </fragment>

Then I have this inside the EvaluationFragment class as a private field:

private val args: EvaluationFragmentArgs by navArgs()

And this inside a method in such class too, that's where the error happens:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        when (args.outcome) {
            EnrollmentOutcome.Accepted -> {
                outcomeTitle.setText(R.string.registration_accepted)
                outcomeIcon.setImageDrawable(
                    ContextCompat.getDrawable(
                        requireContext(),
                        R.drawable.ic_check_circle_green_48dp
                    )
                )
                outcomeDescription.setText(R.string.registration_description_accepted)
            }
            EnrollmentOutcome.Rejected -> {
                outcomeTitle.setText(R.string.registration_declined)
                outcomeDescription.setText(R.string.registration_description_declined)
                outcomeIcon.setImageDrawable(
                    ContextCompat.getDrawable(
                        requireContext(),
                        R.drawable.ic_error_red_48dp
                    )
                )
            }
            EnrollmentOutcome.Reviewing -> {
                outcomeTitle.setText(R.string.registration_reviewing)
                outcomeDescription.setText(R.string.registration_description_reviewing)
                outcomeIcon.setImageDrawable(
                    ContextCompat.getDrawable(
                        requireContext(),
                        R.drawable.ic_info_blue_48dp
                    )
                )
            }
            EnrollmentOutcome.Unknown -> {
                outcomeTitle.setText(R.string.registration_error)
                outcomeDescription.setText(R.string.registration_description_error)
                outcomeIcon.setImageDrawable(
                    ContextCompat.getDrawable(
                        requireContext(), R.drawable.ic_error_red_48dp
                    )
                )
            }
        }
    }

Now the problem is that in each of these when branches the enum item is underlined in red by Android Studio and show this error:

Comparison of incompatible enums '[ERROR : com.whatever.domain.EvaluationFragment$EnrollmentOutcome]' and 'EvaluationFragment.EnrollmentOutcome' is always unsuccessful

In spite of that, the code not only does build perfectly well but it works exactly as expected.

In any case I'd like to know why is Android Studio throwing an error there and how I could get rid of it and still use the enum in safe args (I mean, I could workaround it easily by passing a String instead and doing the required conversions for which I already have a method in the enum itself, but that kinda defeat the point of using Safe Args, doesn't it?).

Thanks a lot in advance, Fran

Discourage answered 22/7, 2021 at 8:42 Comment(0)
B
1

I'm not sure what is causing that error from Android Studio but I do know how to remove that error.

Within your nav_graph.xml you have the argType set to the enum within a class. If you move the enum outside of the class, then change the argType to match to where it was moved to (just remove the class name with the $) then it'll have no issues

Bergh answered 7/12, 2021 at 12:29 Comment(1)
Thanks James, I'll try to confirm that. In any case is clearly a bug in AS since it should be able to deal also with nested enums, which are quite common and convenient.Discourage

© 2022 - 2024 — McMap. All rights reserved.