Issue
I have created Navigation Drawer Activity:
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
}
And I have mobile_navigation.xml
:
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/mobile_navigation"
app:startDestination="@id/databaseFragment">
<fragment
android:id="@+id/databaseFragment"
android:name="com.acmpo6ou.myaccounts.ui.DatabaseFragment"
android:label="fragment_database_list"
tools:layout="@layout/fragment_database_list" >
<action
android:id="@+id/actionCreateDatabase"
app:destination="@id/createDatabaseFragment" />
</fragment>
<fragment
android:id="@+id/createDatabaseFragment"
android:name="com.acmpo6ou.myaccounts.ui.CreateDatabaseFragment"
android:label="create_edit_database_fragment"
tools:layout="@layout/create_edit_database_fragment" />
</navigation>
The start destination is DatabaseFragment
. However there is a problem, here is my DatabaseFragment
:
class DatabaseFragment(
override val adapter: DatabasesAdapterInter,
val presenter: DatabasesPresenterInter
) : Fragment(), DatabaseFragmentInter {
...
companion object {
@JvmStatic
fun newInstance(
adapter: DatabasesAdapterInter,
presenter: DatabasesPresenterInter
) = DatabaseFragment(adapter, presenter)
}
}
As you can see my DatabaseFragment
should receive two arguments to its constructor: adapter
and presenter
. This is because of dependency injection, in my tests I can instantiate DatabaseFragment
passing through mocked adapter
and presenter
. Like this:
...
val adapter = mock<DatabasesAdapterInter>()
val presenter = mock<DatabasesPresenterInter>()
val fragment = DatabaseFragment(adapter, presenter)
...
It works with tests, but it doesn't work with android navigation. It seems that Android Navigation Components create DatabaseFragment
instead of me, but they don't pass any arguments to fragment's constructor and it fails with error that is too long to post it here.
Is there a way to tell Navigation Components so that they pass appropriate arguments to my fragments when instantiating them?
Thanks!
Solution
Short answer is no, you can not pass arguments to Fragment
.
All subclasses of Fragment
must include a public no-argument constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it. If the no-argument constructor is not available, a runtime exception will occur in some cases during state restore.
Answered By - i30mb1
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.