DaveNOTDavid
DaveNOTDavid

Reputation: 1803

Kotlin: Declaring subclasses of an Activity static

After converting Java code to Kotlin for an Activity consisting of a subclass Fragment, the layouts won't render appropriately anymore (logcat errors towards the bottom of this post). I figured because declaring subclasses of an Activity must be declared publicly static, and this is what I have after converting to Kotlin:

class SettingsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_settings)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == android.R.id.home) {
            finish()

            return true
        }

        return super.onOptionsItemSelected(item)
    }

    // Apparently the following class must be declared static.
    class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener {

        override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
            addPreferencesFromResource(R.xml.settings_main)
        }

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
        }

        override fun onDestroy() {
            super.onDestroy()
        }
    }
}

... I tried changing the fragment's modifier to "object" and even stored the whole class within a companion object, and yet the app crashed with the same exceptions.

Here's my fragment XML:

<?xml version="1.0" encoding="utf-8"?>
<fragment
    android:id="@+id/fragment"
    android:name="com.davenotdavid.dndheadlines.SettingsActivity$SettingsFragment"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</fragment>

Exceptions thrown:

Caused by: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class fragment                                                                          
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment                                                                          
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState

... All of that said, how do I properly declare subclasses of an Activity publicly static?

Upvotes: 2

Views: 703

Answers (2)

Submersed
Submersed

Reputation: 8870

It looks like it's a null safety issue from your stack trace. Since you're allowing nulls on each of the other Bundle related methods, have you tried adding:

  override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String) {
        addPreferencesFromResource(R.xml.settings_main)
    }

Upvotes: 2

zsmb13
zsmb13

Reputation: 89578

Speaking in Java parlance, a class nested in another is static by default in Kotlin (and all classes are public by default). This shouldn't be a problem.

You are getting an exception because of nullability though: you should make your savedInstanceState parameter in onCreatePreferences a nullable Bundle?, because this function may be called by the framework with a null value, and it will crash your app every time that it is if the type here is non-nullable.

So what you want to end up with is this:

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String) {
    addPreferencesFromResource(R.xml.settings_main)
}

Upvotes: 3

Related Questions