0

I have an application composed of one activity and several fragments, as recommanded by Google. Other details here. I would like to keep a menu still and to switch my fragments in the container in the center.

activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:someProperties="propertiesValues">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:someProperties="propertiesValues" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/navigation_map"
        />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:someProperties="propertiesValues" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

activity_main.xml

MainActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        println("Activity creation")
        val binding = ActivityMainBinding.inflate(layoutInflater)
        println("Activity creation part 2")
        setContentView(binding.root)
        setSupportActionBar(binding.toolbar)

        User.initSharedPref(this)
    }

Fragment

private lateinit var mylist: MutableList<String>>
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    println("Fragment creation")

    mylist = User.loadScenarioList()
}

User

object User
{
  private lateinit var sharedPref : SharedPreferences

  fun initSharedPref(context: Context){
    sharedPref = context.getSharedPreferences("JeuDePisteKtPreferenceFileKey",Context.MODE_PRIVATE)
  }

  fun loadList(): MutableList<String>> {
      val json = sharedPref.getString(KEY_LIST, "") ?: ""
      if (json == "") return mutableListOf()
      return Json.decodeFromString(json)
  }

}

Problem encountered

When i start the activity, it initialize a variable sharedPref as shown in code.

But when in fragment onCreate i use this variable (mylist = User.loadScenarioList()), the binding line in activity fail with Binary XML file line #31: Error inflating class androidx.fragment.app.FragmentContainerView as shown in logcat below

Logcat & error

Here is the full logcat, we can see the the second sout is missing, but with no error thrown at this point.

logcat

Foxhunt
  • 764
  • 1
  • 9
  • 23
  • 2
    There is never a crash without an error message. Check to make sure Logcat is working correctly and not filtering you logs. The question you linked is irrelevant for an Activity. This is the right place to inflate the view in an Activity, and your code looks fine. – Tenfour04 Oct 28 '21 at 23:56
  • 1
    Care to elaborate the `menu` here is ActionBar menu or those `fab` button? – Putra Nugraha Oct 29 '21 at 00:38
  • The crash actually happen later because a Lateinit property i initialise at the end of my Activity.OnCreate() is used in my Fragment.OnCreate(). For debug i also added print, wich is not reach, but without error. i added it above with the logcat – Foxhunt Oct 29 '21 at 09:02
  • I spoted the problem more precisly, changed the question with it. The real error is sort of mixed with the fragment error, but i did a breakpoint just before the line `ActivityMainBinding.inflate(layoutInflater)`, and then evaluate it, and it return `Binary XML file line #31: Error inflating class androidx.fragment.app.FragmentContainerView` – Foxhunt Oct 29 '21 at 16:56

1 Answers1

0

The problem here came from the order of creation call

We can see it in the corrected code logcat logcat

The activity onCreate is called first, but the first inflate call the fragment OnCreate, before resuming the activity OnCreate.

So every variable used in the fragment onCreate should be initialized before inflate call

Foxhunt
  • 764
  • 1
  • 9
  • 23