Home > other >  Error using <FragmentContainerView>, but no error with <fragment>
Error using <FragmentContainerView>, but no error with <fragment>

Time:08-25

I am developing a mobile app and I am currently trying to rework my workflow to more appropriately leverage Activities and Fragments for their intended purposes and I have run across a strange issue I can't figure out. I have a fragment I am trying to add to an Activity, but what I try and use FragmentContainerView, the app crashes on launch, but it doesn't happen when I just use a tag with all the same attributes. In looking at the Logcat, the error comes from null being assigned to the last line of the utils file where it tries to assign to topAppBar view the view with an id of top_app_bar. Here is the relevant code:

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    fragmentManager.beginTransaction().replace(R.id.frame_layout, HomeFragment()).commit()
    utils = Utils(this)
    topAppBar = findViewById(R.id.top_app_bar)
    drawerLayout = findViewById(R.id.drawer_layout)
    val navigationView: NavigationView = findViewById(R.id.navigation_view)

    topAppBar.setNavigationOnClickListener {
        if (!drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.openDrawer(GravityCompat.START)
        }
        else {
            drawerLayout.closeDrawer(GravityCompat.START)
        }
    }
    navigationView.setNavigationItemSelectedListener { item ->
        val id: Int = item.itemId
        drawerLayout.closeDrawer(GravityCompat.START)
        when (id) {
            R.id.navigation_home -> { utils.replaceFragment(HomeFragment(), getString(R.string.app_name)) }
            R.id.navigation_recipes -> { utils.replaceActivity(this, item.title.toString().lowercase()) }
            R.id.navigation_budget -> { utils.replaceActivity(this, item.title.toString().lowercase()) }
            R.id.navigation_inventory -> { utils.replaceActivity(this, item.title.toString().lowercase()) }
            R.id.navigation_customers -> { utils.replaceActivity(this, item.title.toString().lowercase()) }
            R.id.navigation_reports -> { utils.replaceActivity(this, item.title.toString().lowercase()) }
        }
        true
    }

activity_main.xml

<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@ id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.bakingapp.ui.TopAppBarFragment"
    tools:layout="@layout/fragment_top_app_bar" />

Utils.kt (There is more to this file, but it is not relevant to the problem)

class Utils(activity: Activity) {
    private var currentActivity: Activity
    private var fragmentManager: FragmentManager
    private var topAppBar: MaterialToolbar
    val activitiesList = listOf("recipes", "budget", "inventory", "customers",
        "reports")

    init {
        currentActivity = activity
        fragmentManager = (activity as AppCompatActivity).supportFragmentManager
        topAppBar = currentActivity.findViewById(R.id.top_app_bar)
    }
}

This works perfectly fine when I use instead of what is currently there, but I get warnings saying I shouldn't use fragment. I should be able to use the more proper tag, but I don't understand why it can't find the view when I use this method, but it can find the view when I use the tag. If someone could explain what is happening here and what I can do to fix the issue, I would really appreciate it.

CodePudding user response:

Step 1 : Add FragmentContainerView to your activity xml

<androidx.fragment.app.FragmentContainerView
     android:id="@ id/container"
     android:layout_width="match_parent"
     android:layout_height="match_parent" />

Step 2 : In your MainActivity.class file, declare FragmentManager

private FragmentManager manager;

Step 3 : Initialize FragmentManager in onCreate()

manager = getSupportFragmentManager();

Step 4 : In your onOptionsItemSelected() begin this fragment

Bundle bundle = new Bundle();
manager.beginTransaction()
                .replace(R.id.container/*Your View Id*/, YourFragment.class, bundle, "TAG")
                .setReorderingAllowed(true)
                //.setCustomAnimations(R.anim.anim_enter, R.anim.anim_exit)
                .addToBackStack("TAG")
                .commit();

CodePudding user response:

Have you tried putting FragmentContainerView inside a layout? Instead of using it as parent layout. That could solve it.

  • Related