4

Let's say we have a project like this one:

class MainActivity : AppCompatActivity() {
    private lateinit var drawerLayout: DrawerLayout
    private lateinit var appBarConfiguration : AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        drawerLayout = binding.drawerLayout
        val navController = this.findNavController(R.id.myNavHostFragment)
        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
        appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
        // prevent nav gesture if not on start destination
        navController.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, bundle: Bundle? ->
            if (nd.id == nc.graph.startDestination) {
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
            } else {
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
            }
        }
        NavigationUI.setupWithNavController(binding.navView, navController)
    }

Link to a simple project: https://github.com/udacity/andfun-kotlin-android-trivia/blob/Step.11-Solution-Adding-Animation/app/src/main/java/com/example/android/navigation/MainActivity.kt

My file for navGraph contains fragments and also one Activity where I want to go if user select its title from the navigation drawer. I want to send some data to this Activity. How can I do it using safe-args?

I'm using:

apply plugin: "androidx.navigation.safeargs"

and

implementation 'androidx.navigation:navigation-fragment:2.0.0'

implementation 'androidx.navigation:navigation-ui:2.0.0'
nasko700
  • 73
  • 1
  • 7
  • You might want to rethink your logic since using a menu only specifies an id for navigation and not an action; which is used for SafeArgs. So either you pass the data in a normal bundle and retrieve with safe args or rethink your structure. – Roach Jun 09 '19 at 19:37
  • "a menu only specifies an id for navigation and not an action" - Not true. If the id refers to an action, the action will in fact be used. – Johann Jun 21 '19 at 10:09

2 Answers2

0

Firstly, you'll have to go to the navigation graph and specify an argument for the activity destination. This can be done via the design UI or in XML like this;

<navigation>
    <activity android:id="@+id/someActivity">
        <argument
            android:name="isEditMode"
            app:argType="boolean"
            android:defaultValue="false" />
    </activity>
</navigation>

This snippet assumes you are passing a boolean to the activity.

At this point, you can build the project so that all required files are generated.

Then in the onClick of whatever Navigation menu item responsible for starting the activity, you pass in the data;

override boolean onNavigationItemSelected(menuItem: menuItem) {

    val id = menuItem.itemId

    when (id) {

       R.id.openActivity -> {
            val bundle = bundleOf("isEditMode" to false) 
            findNavController().navigate(R.id.someActivity, bundle)
       }
    }
    return true
}

Then in your activity, get the pass data safely as;

val safeArguments: MyActivityArgs by navArgs()
val isEditMode = safeArgs.isEditMode)
Roach
  • 610
  • 1
  • 8
  • 13
  • 1
    I needed to make it without using `onNavigationItemSelected` because it's already done with the graph and navcontroller. At the end I added the data programatically as default values `NavArgument isDemoTrueArgument = new NavArgument.Builder().setType(NavType.BoolType).setDefaultValue(true).build(); NavGraph graph = navController.getGraph(); NavDestination demoDestination = graph.findNode(R.id.nav_demo); demoDestination.addArgument("is_demo", isDemoTrueArgument);` – nasko700 Jun 12 '19 at 20:17
0

Inside your onCreate method in MainActivity use this:

val navController = this.findNavController(R.id.myNavHostFragment)

navController.addOnDestinationChangedListener { controller, destination, arguments ->
    when(destination.id) {
        R.id.caixaFragment -> {
            var myVar = someMethodThatBringsMyVarValue()
            val argument = NavArgument.Builder().setDefaultValue(mayVar).build()
            destination.addArgument("idMes", argument)
        }
    }
}

I got it from Ayxan Haqverdili in this question

Michel Fernandes
  • 1,187
  • 9
  • 8