<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by ashita asati on Medium]]></title>
        <description><![CDATA[Stories by ashita asati on Medium]]></description>
        <link>https://medium.com/@ashitaasati1608?source=rss-5a7a8a59b784------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*lLop7p2NuRkHQl1y.</url>
            <title>Stories by ashita asati on Medium</title>
            <link>https://medium.com/@ashitaasati1608?source=rss-5a7a8a59b784------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 00:53:35 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ashitaasati1608/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Implementing In-App Updates in Android]]></title>
            <link>https://medium.com/swlh/implementing-in-app-updates-in-android-26ea27609bd2?source=rss-5a7a8a59b784------2</link>
            <guid isPermaLink="false">https://medium.com/p/26ea27609bd2</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[ashita asati]]></dc:creator>
            <pubDate>Sun, 28 Jun 2020 18:59:08 GMT</pubDate>
            <atom:updated>2020-07-16T23:54:58.854Z</atom:updated>
            <content:encoded><![CDATA[<p>I’m sure we all must have come across the situations while working on the applications where we needed to send out an app update can say like a hotfix — maybe there’s a security issue or some bug which will break the experience for the users. In such scenarios earlier, we’ve needed to roll out a new update on the Google play store and wait for our users to receive the update. And if they don’t have automatic updates installed, we rely on the user visiting the play store to update our application or we send out a force update to the users.</p><p>Keeping your app up-to-date on your users’ devices enables them to try new features, as well as benefit from performance improvements and bug fixes.</p><p>In-app updates is a Play Core library feature that introduces a new request flow to prompt active users to update your app.</p><p>In simple words, it provides an option to the user which notifies the user that an app update is available and the user can select if they are interested in updating the app or not.</p><p>Not only that, but it also provides an option to download the update of the app in the background, and once downloaded, install the update and restart the app and the user doesn’t have to do anything.</p><blockquote>In-app updates work only with devices running Android 5.0 (API level 21) or higher and require you to <a href="https://developer.android.com/guide/playcore/dynamic-delivery#include_playcore">use Play Core library</a> 1.5.0 or higher. Additionally, in-app updates support apps running on only Android mobile devices and tablets, and Chrome OS devices.</blockquote><p>The Play Core library offers us two different ways in which we can prompt our users that an update is available — either using the <strong>Flexible</strong> or <strong>Immediate</strong> approach. Let’s take a look at each of them one by one-</p><p><strong>Flexible:</strong> A user experience that provides background download and installation with graceful state monitoring. This UX is appropriate when it’s acceptable for the user to use the app while downloading the update. For example, you want to urge users to try a new feature that’s not critical to the core functionality of your app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/825/1*ZSMFKoplS4H4D4O6PADSUg.png" /><figcaption>Flexible Update Flow</figcaption></figure><p><strong>Immediate:</strong> A full-screen user experience that requires the user to update and restart the app to continue using the app. This UX is best for cases where an update is critical for continued use of the app. After a user accepts an immediate update, Google Play handles the update installation and app restart.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/528/1*nBbBDKQro5ga2R5Cn8tjCg.png" /><figcaption>Immediate Update Flow</figcaption></figure><p>Now we all have an understanding of both the types of In-app updates available we will start implementing it.</p><p>The very first step is to <strong>check for the update</strong>-</p><p>Before requesting an update, you need to check if an update is available or not and also the type of update available. We do not want users to have a bad experience. To check for an update you can use the <strong><em>AppUpdateManager.</em></strong></p><pre><strong>val </strong>appUpdateManager: AppUpdateManager = AppUpdateManagerFactory.create(<em>baseContext</em>)</pre><pre><strong>val </strong>appUpdateInfo = appUpdateManager.<em>appUpdateInfo<br></em>// Creates instance of the manager.<br>val appUpdateManager = AppUpdateManagerFactory.create(context)</pre><pre>// Returns an intent object that you use to check for an update.<br><strong>val </strong>appUpdateInfoTask = appUpdateManager.<em>appUpdateInfo</em></pre><pre>// Checks that the platform will allow the specified type of update.<br>appUpdateInfo?.addOnSuccessListener <strong>{ </strong>appUpdateInfo -&gt;<strong><br>    if </strong>((appUpdateInfo.updateAvailability() == UpdateAvailability.<em>UPDATE_AVAILABLE </em>||<br>            appUpdateInfo.updateAvailability() == UpdateAvailability.<em>DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS</em>) &amp;&amp;<br>    appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.<em>FLEXIBLE</em>)<br>) {<br>    btn_update.<em>visibility </em>= View.<em>VISIBLE<br>    </em>setUpdateAction(appUpdateManager, appUpdateInfo)<br>  }<br><strong>}</strong></pre><p>Here we have created a button to show some UX experience. Whenever there will be a flexible update available we will show the update button to the users. As we have an update available of flexible types, we will start the update.</p><pre><strong>private fun </strong>setUpdateAction(manager: AppUpdateManager?, info: Task&lt;AppUpdateInfo&gt;) {<br>    <em>// Before starting an update, register a listener for updates.</em></pre><pre>btn_update.setOnClickListener <strong>{<br>        installStateUpdatedListener </strong>= <em>InstallStateUpdatedListener </em><strong>{<br>            </strong>btn_update.<em>visibility </em>= View.<em>GONE<br>            // tv_status is a textview to display the update status      <br>            </em>tv_status.<em>visibility </em>= View.<em>VISIBLE<br>            </em><strong>when </strong>(<strong>it</strong>.installStatus()) {<br>                InstallStatus.<em>FAILED</em>, InstallStatus.<em>UNKNOWN </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_failed</em>)<br>                    btn_update.<em>visibility </em>= View.<em>VISIBLE<br>                </em>}<br>                InstallStatus.<em>PENDING </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_pending</em>)<br>                }<br>                InstallStatus.<em>CANCELED </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_canceled</em>)<br>                }<br>                InstallStatus.<em>DOWNLOADING </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_downloading</em>)<br>                }<br>                InstallStatus.<em>DOWNLOADED </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_downloaded</em>)<br>                    popupSnackbarForCompleteUpdate(manager)<br>                }<br>                InstallStatus.<em>INSTALLING </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_installing</em>)<br>                }<br>                InstallStatus.<em>INSTALLED </em>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_installed</em>)<br>                    manager?.unregisterListener(<strong>installStateUpdatedListener</strong>)<br>                }<br>                <strong>else </strong>-&gt; {<br>                    tv_status.<em>text </em>= getString(R.string.<em>info_restart</em>)<br>                }<br>            }<br>        <strong>}<br>        </strong>manager?.registerListener(<strong>installStateUpdatedListener</strong>)<br>        manager?.startUpdateFlowForResult(            info.<em>result</em>, AppUpdateType.<em>FLEXIBLE</em>,<br>            <strong>this</strong>, <strong>IN_APP_UPDATE_REQUEST_CODE<br>        </strong>)<br>    <strong>}<br></strong>}</pre><p>While doing the update, you can handle the update related failure or cancellation by using the <strong>onActivityResult()<em> </em></strong>as follows:</p><pre><em>/** This is needed to handle the result of the manager.startConfirmationDialogForResult request */<br></em><strong>override fun </strong>onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {<br>    <strong>if </strong>(requestCode == <strong>IN_APP_UPDATE_REQUEST_CODE</strong>) {<br>        <strong>if </strong>(resultCode != <em>RESULT_OK</em>) {<br>            toastAndLog(<strong>&quot;Update flow failed! Result code: $</strong>resultCode<strong>&quot;</strong>)<br>            <em>// If the update is cancelled or fails,<br>            // you can request to start the update again.<br>        </em>}<br>    } <strong>else </strong>{<br>        <strong>super</strong>.onActivityResult(requestCode, resultCode, data)<br>    }<br>}</pre><p>The following describes the different values you may receive from the onActivityResult() callback:</p><ul><li><a href="https://developer.android.com/reference/android/app/Activity#RESULT_OK">RESULT_OK</a>: The user has accepted the update. For immediate updates, you might not receive this callback because the update should already be completed by Google Play by the time the control is given back to your app.</li><li><a href="https://developer.android.com/reference/android/app/Activity#RESULT_CANCELED">RESULT_CANCELED</a>: The user has denied or canceled the update.</li><li><a href="https://developer.android.com/reference/com/google/android/play/core/install/model/ActivityResult#RESULT_IN_APP_UPDATE_FAILED">ActivityResult.RESULT_IN_APP_UPDATE_FAILED</a>: Some other error prevented either the user from providing consent or the update to proceed.</li></ul><p><strong>Install a Flexible Update</strong></p><p>If you monitor the flexible update states and you detect the InstallStatus.DOWNLOADED state, you need to restart the app to install the update.</p><p>Unlike an immediate update, Google Play does not trigger an app restart for you. That’s because, during a flexible update, the user expects to keep using the app until they decide that they want to install the update.</p><p>So, it’s recommended that you provide the user some notification or UI indication to notify that an update is ready for installation and requests user confirmation to restart the app.</p><p>Here we will implement a snackbar to request the user confirmation to restart the app.</p><pre><em>/* Displays the snackbar notification and call to action. */<br></em><strong>private fun </strong>popupSnackbarForCompleteUpdate(appUpdateManager: AppUpdateManager?) {<br>    Snackbar.make(<br>        findViewById(R.id.<em>mainLayoutParent</em>),<br>        <strong>&quot;Ready to INSTALL.&quot;</strong>, Snackbar.<em>LENGTH_INDEFINITE<br>    </em>).<em>apply </em><strong>{<br>        </strong>setAction(<strong>&quot;RESTART&quot;</strong>) <strong>{ </strong>appUpdateManager?.completeUpdate() <strong>}<br>        </strong>setActionTextColor(ContextCompat.getColor(<em>applicationContext</em>, R.color.<em>colorAccent</em>))<br>        show()<br>    <strong>}<br></strong>}</pre><p>When you call appUpdateManager?.completeUpdate() in the foreground, the platform displays a full-screen UI which restarts the app in the background. After the platform installs the update, the app restarts into its main activity.</p><p>If you instead call appUpdateManager?.completeUpdate() when the app is in the background, the update is installed silently without obscuring the device UI.</p><p>When the user brings your app to the foreground, it’s recommended that you check that your app doesn’t have an update waiting to be installed. If your app has an update in the DOWNLOADED state, show the notification to request that the user install the update, as shown. Otherwise, the update data continues to occupy the user’s device storage.</p><pre>// Checks that the update is not stalled during &#39;onResume()&#39;.<br>// However, you should execute this check at all app entry points.<br>override fun onResume() {<br>    super.onResume()<br><br>    appUpdateManager.appUpdateInfo<br>        .addOnSuccessListener {<br>            if (it.updateAvailability() == UpdateAvailability.<em>UPDATE_AVAILABLE</em> || UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {<br>                updateManager.startUpdateFlowForResult(<br>                    it,<br>                    IMMEDIATE,<br>                    this,<br>                    <strong>IN_APP_UPDATE_REQUEST_CODE</strong>)<br>            }<br>        }<br>    }<br>}</pre><h4>Handle an immediate update</h4><p>If you are performing an immediate update, and the user consents to install the update, Google Play displays the update progress on top of your app’s UI across the entire duration of the update. During the update, if the user closes or terminates your app, the update should continue to download and install in the background without additional user confirmation.</p><pre>appUpdateInfo?.addOnSuccessListener <strong>{ </strong>appUpdateInfo -&gt;<strong><br>    if </strong>((appUpdateInfo.updateAvailability() == UpdateAvailability.<em>UPDATE_AVAILABLE </em>||<br>            appUpdateInfo.updateAvailability() == UpdateAvailability.<em>DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS</em>) &amp;&amp;<br>    appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.<em>IMMEDIATE</em>)<br>) {<br>    updateManager.startUpdateFlowForResult(it, IMMEDIATE, this,  <strong>IN_APP_UPDATE_REQUEST_CODE</strong>)<br>  }<br><strong>}</strong></pre><p>To check how to test In-app updates please refer: <a href="https://developer.android.com/guide/playcore/in-app-updates">https://developer.android.com/guide/playcore/in-app-updates</a></p><h3><strong>Conclusion</strong></h3><p>In this blog, we’ve learned about the new approach to in-app updates that are provided by the play core library. You can also check out how to set the appUpdatePriority and clientVersionStalenessDays.</p><p>Do checkout my GitHub repo for the implementation</p><p><a href="https://github.com/ashitaasati1608/InAppUpdate">https://github.com/ashitaasati1608/InAppUpdate</a></p><p>If you have any questions about the play core library or in-app updates then please do reach out.</p><p>Happy Coding!!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=26ea27609bd2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/implementing-in-app-updates-in-android-26ea27609bd2">Implementing In-App Updates in Android</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android Navigation Component]]></title>
            <link>https://medium.com/@ashitaasati1608/android-navigation-component-89174d51b690?source=rss-5a7a8a59b784------2</link>
            <guid isPermaLink="false">https://medium.com/p/89174d51b690</guid>
            <category><![CDATA[navigation-component]]></category>
            <category><![CDATA[android-studio]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[ashita asati]]></dc:creator>
            <pubDate>Sun, 10 May 2020 16:15:46 GMT</pubDate>
            <atom:updated>2020-05-11T05:08:37.285Z</atom:updated>
            <content:encoded><![CDATA[<p><em>In this article, we’ll see what exactly is Navigation component and how to implement it.</em></p><h3>What’s Navigation Component?</h3><p>We all know that navigating between screens is one of the fundamental things in an Android application. Usually, we either achieve it through Intents or via Event Bus but what about the complex scenarios like navigation drawer or bottom navigation where you need to keep the selected tab highlighted in sync with the presented screen not to mention back-stack management? Isn’t it a bit complex to achieve this way?</p><p>Navigation component is the one-stop solution to all the problems for any type of navigation in an android app<em>. </em>The navigation component helps you to manage navigations, fragment transactions, back-stack management, animations, most importantly deep linking and many more. The JetPack Navigation component is a suite of libraries, tooling, and guidance that provides a robust navigation framework for in-app navigation.</p><p>The navigation component provides a new type of navigation in android development, where we have a navigation graph to see all the screens and the navigation between them.</p><p><strong>Let’s talk about the key parts of the Navigation component. Navigation component consists of three key types</strong></p><ul><li><strong>Navigation graph:</strong> An XML resource that contains all navigation-related information in one centralized location. This includes all of the individual content areas within your app, called <em>destinations</em>, as well as the possible paths that a user can take through your app.</li><li><strong>NavHost:</strong> An empty container that displays destinations from your navigation graph.</li><li><strong>NavController:</strong> An object that manages app navigation within a NavHost. The NavController orchestrates the swapping of destination content in the NavHost as users move throughout your app.</li></ul><p>I’ll explain two more terminologies here as we are going to use them very often-</p><ul><li><strong>Destinations: </strong>Destinations are nothing but all content areas in your app like activities, fragments, dialogs, and so on.</li><li><strong>Actions: </strong>Action is used to create a navigation that has an attribute called destination, where we can mention the end screen id.</li></ul><blockquote>When we navigate through the app using the NavController, the NavController shows the appropriate destination in the NavHost.</blockquote><p>The Navigation component provides several other benefits, including the following:</p><ul><li>Simplified setup for common navigation patterns</li><li>Handling fragment transactions.</li><li>Type safe when passing information while navigating</li><li>Handles transition animations</li><li>Centralizes and visualizes navigation</li><li>Handling Up and Back actions correctly by default.</li><li>Providing standardized resources for animations and transitions.</li><li>Implementing and handling deep linking.</li></ul><p>Okay, so we are now familiar with the Navigation component and benefits. Now it’s time to get our hands dirty with implementing a basic navigation flow.</p><p><strong>So what are we going to build?</strong></p><p>We will build a basic application with three screens(Main Activity with three fragments with two buttons each) and establish the navigation between them.</p><p><em>Let’s get started…</em></p><p><strong>Prerequisites:</strong></p><ul><li>Basic Kotlin knowledge</li><li>Android Studio 3.2 or higher</li><li>Emulator or device running API 14+</li></ul><p>After creating the basic Android project, add the below dependency in the top-level <strong><em>build.gradle</em></strong> file.</p><pre><strong>def </strong>nav_version = <strong>&quot;2.1.0&quot;</strong></pre><pre>dependencies <strong>{<br>    </strong>classpath <strong>&quot;androidx.navigation:navigation-safe-args-gradle-plugin:</strong>$nav_version<strong>&quot;</strong><em><br></em><strong>}</strong></pre><p>Now, add the below dependencies in your app-level build.gradle, and once done click on sync now!</p><pre>apply <strong>plugin</strong>: <strong>&quot;androidx.navigation.safeargs.kotlin&quot;</strong></pre><pre>android {<br>    ...<br>    compileOptions {<br>        sourceCompatibility JavaVersion.VERSION_1_8<br>        targetCompatibility JavaVersion.VERSION_1_8<br>    }</pre><pre>kotlinOptions {<br>        jvmTarget = JavaVersion.VERSION_1_8.toString()<br>    }<br>}</pre><pre><strong>def </strong>nav_version = <strong>&quot;2.2.2&quot;<br></strong>dependencies <strong>{<br></strong>implementation <strong>&quot;androidx.navigation:navigation-fragment ktx:</strong>$nav_version<strong>&quot;<br></strong>implementation <strong>&quot;androidx.navigation:navigation-ui-ktx:</strong>$nav_version<strong>&quot;<br>}</strong></pre><blockquote><strong>Safe Arguments : </strong>Safe Args is a Gradle plugin used to pass data between destinations. The main advantage of using safe args is that some of the checks that happen at runtime will now be done at compile time.</blockquote><p>You’re good to go now!!!</p><p>Firstly, we will create a Navigation Graph for our application.</p><p>The question arises here is how to create a navigation Graph???</p><p>As we learned earlier that a navigation graph is nothing but a resource file with all navigation related information, so we create a resource file under <strong>res </strong>directory with resource type as navigation.</p><p>Steps to creating a navigation graph:</p><ol><li>In the Project window, right-click on the res directory and select <strong>New &gt; Android Resource File </strong>under<strong> </strong><em>navigation directory</em>. If you haven’t created then create one.</li><li>In the <em>navigation </em>directory, we’ll create a new <strong><em>navigation resource file. </em></strong>In this example, I’ve named it <strong><em>navigation</em></strong> but you can name it whatever you like.</li><li>Select <strong>Navigation</strong> from the <strong>Resource type</strong> drop-down list, and then click <strong>OK</strong>.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GRpDzuuOt0FbK1LPv9Q8QA.png" /><figcaption>Creating a navigation graph file</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/814/1*9lL7x-FvzsKmZVFQxOh35A.png" /><figcaption>Navigation graph in the project panel</figcaption></figure><p>Now, we will modify out activity_main.xml and replace the default <strong><em>&lt;TextView/&gt;</em></strong> with the <strong><em>&lt;fragment/&gt;</em></strong> given below-</p><pre>&lt;<strong>fragment<br>    android:id=&quot;@+id/fragment&quot;<br>    android:name=&quot;androidx.navigation.fragment.NavHostFragment&quot;<br>    android:layout_width=&quot;0dp&quot;<br>    android:layout_height=&quot;0dp&quot;<br>    app:defaultNavHost=&quot;true&quot;<br>    app:layout_constraintBottom_toBottomOf=&quot;parent&quot;<br>    app:layout_constraintEnd_toEndOf=&quot;parent&quot;<br>    app:layout_constraintStart_toStartOf=&quot;parent&quot;<br>    app:layout_constraintTop_toTopOf=&quot;parent&quot;<br>    app:navGraph=&quot;@navigation/navigation&quot; </strong>/&gt;</pre><p>Once we’ve done that, we should see a host (activity_main) added to the Navigation graph (in <em>navigation.xml</em>)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1uVeFzOqC14T9a41gfE0Ew.png" /><figcaption>Navigation graph with a host</figcaption></figure><p>Now we can add a new destination by clicking on the ‘<em>Click to add a destination</em>’ option in the center of the navigation graph. Then select ‘create new destination’ options, this will open Android New Component Dialog where we can create a new Fragment.</p><p>For this example, we’ll have two fragments namely — <em>SignupFragment and LoginFragment</em>. After creating these Fragments, click on the fragment and attach it to the other one. The navigation graph should look something like this —</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WDdXXe3bL3RlgdveTyESFA.png" /><figcaption>Navigation Graph with a single action</figcaption></figure><p>navigation.xml will look something like this for the above Navigation Graph-</p><pre><em>&lt;?</em><strong>xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;</strong><em>?&gt;<br></em>&lt;<strong>navigation xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br>    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;<br>    xmlns:tools=&quot;http://schemas.android.com/tools&quot;<br>    android:id=&quot;@+id/navigation_graph&quot;<br>    app:startDestination=&quot;@id/signupFragment3&quot;</strong>&gt;<br>    &lt;<strong>fragment<br>        android:id=&quot;@+id/signupFragment3&quot;<br>        android:name=&quot;com.navigation.view.SignupFragment&quot;<br>        android:label=&quot;fragment_signup&quot;<br>        tools:layout=&quot;@layout/fragment_signup&quot; </strong>&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/action_signupFragment3_to_loginFragment3&quot;<br>            app:destination=&quot;@id/loginFragment3&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>    &lt;<strong>fragment<br>        android:id=&quot;@+id/loginFragment3&quot;<br>        android:name=&quot;com.navigation.view.LoginFragment&quot;<br>        android:label=&quot;fragment_login&quot;<br>        tools:layout=&quot;@layout/fragment_login&quot; </strong>&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/action_loginFragment3_to_signupFragment3&quot;<br>            app:destination=&quot;@id/signupFragment3&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>&lt;/<strong>navigation</strong>&gt;</pre><p>Here the root tag will be navigation<strong> </strong>with startDestination attribute in which we mention the id of the fragment to be loaded initially followed by destinations, like fragments, dialogs and so on, with one of the attributes name, whose value will be the name of your destination.</p><p>Now we come to the navigation. We use a tag action under a specific destination — where we want to initiate the navigation. There’s also an attribute in which we mention the destination ID.</p><p>The <em>SignupFragment</em> layout will have two Buttons (with id’s as — <em>signupBtn </em>and <em>gotoLoginBtn</em>) and three EditText( with id — <em>signupUsername, signupPassword, otherInfo</em>).</p><pre><strong>override fun </strong>onViewCreated(view: View, savedInstanceState: Bundle?) {<br>    <strong>super</strong>.onViewCreated(view, savedInstanceState)<strong><br>    </strong>gotoLoginBtn.setOnClickListener <strong>{ </strong>onGotoLogin(<strong>it</strong>)</pre><pre>}</pre><pre><strong>private fun </strong>onGotoLogin(v: View) {<br>    <strong>val </strong>action = SignupFragmentDirections.actionGoToLogin()<br>    Navigation.findNavController(v).navigate(action)<br>}</pre><p>Type safe dependency will generate class in the format of <strong>name_of_file_Directions </strong>(In our case source fragment <strong>SignupFragmentDirections</strong>) which consists the <strong>&lt;action&gt;&lt;/action&gt; </strong>in<strong> </strong>navigation file<strong> (navigation).</strong></p><p>Now we will try to create a Navigation Graph with multiple actions. Let me show you how the navigation graph will look with three fragments and multiple actions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I0ujSaoofUw_4Fj1IBgE4A.png" /><figcaption>Navigation graph with multiple actions</figcaption></figure><p>Now let’s take a look at the XML code in the navigation tab to create a graph like above:</p><pre><em>&lt;?</em><strong>xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;</strong><em>?&gt;<br></em>&lt;<strong>navigation xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br>    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;<br>    xmlns:tools=&quot;http://schemas.android.com/tools&quot;<br>    android:id=&quot;@+id/navigation&quot;<br>    app:startDestination=&quot;@id/signupFragment&quot;</strong>&gt;</pre><pre>&lt;<strong>fragment<br>        android:id=&quot;@+id/signupFragment&quot;<br>        android:name=&quot;com.navigation.view.SignupFragment&quot;<br>        android:label=&quot;fragment_signup&quot;<br>        tools:layout=&quot;@layout/fragment_signup&quot;</strong>&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToMain&quot;<br>            app:destination=&quot;@id/mainFragment&quot; </strong>/&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToLogin&quot;<br>            app:destination=&quot;@id/loginFragment&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>    &lt;<strong>fragment<br>        android:id=&quot;@+id/loginFragment&quot;<br>        android:name=&quot;com.navigation.view.LoginFragment&quot;<br>        android:label=&quot;fragment_login&quot;<br>        tools:layout=&quot;@layout/fragment_login&quot;</strong>&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToMain&quot;<br>            app:destination=&quot;@id/mainFragment&quot; </strong>/&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToSignup&quot;<br>            app:destination=&quot;@id/signupFragment&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>    &lt;<strong>fragment<br>        android:id=&quot;@+id/mainFragment&quot;<br>        android:name=&quot;com.navigation.view.MainFragment&quot;<br>        android:label=&quot;fragment_main&quot;<br>        tools:layout=&quot;@layout/fragment_main&quot;</strong>&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToSignup&quot;<br>            app:destination=&quot;@id/signupFragment&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>&lt;/<strong>navigation</strong>&gt;</pre><p>That’s it. Basic navigation is implemented in your app. You will be able to navigate to the LoginFragment with this.</p><p>Now as we have learned Basic implementation we will see how to implement <strong>Navigation With Arguments:</strong></p><p>We can achieve this in two possible ways.</p><ol><li>Using bundles</li><li>Using SafeArgs</li></ol><p>Here I’ll implement it in both the ways and will also explain how passing data with SafeArgs is better than passing data through bundles.</p><p><strong>Using Bundles: </strong>Pass data from the source fragment by getting the nav controller of view as</p><pre><strong>val </strong>bundle = <em>bundleOf</em>(<strong>&quot;username&quot; </strong><em>to </em>signupUsername.<em>text</em>.toString())<br>Navigation.findNavController(signupUsername).navigate(R.id.<em>actionGoToMain</em>, bundle)</pre><p><strong>bundleOf() </strong>is the extension method of androidx. For that, we need to add below dependency in the app-level build.gradle file:</p><pre>implementation <strong>&#39;androidx.core:core-ktx:1.3.0-rc01&#39;</strong></pre><p>Receive data in destination fragment as :</p><pre><strong>override fun </strong>onViewCreated(view: View, savedInstanceState: Bundle?) {<br>    <strong>super</strong>.onViewCreated(view, savedInstanceState)</pre><pre>signoutBtn.setOnClickListener <strong>{ </strong>onSignout() <strong>}<br>    </strong>usernameTV.<em>text </em>= <strong>&quot;Hello &quot;</strong>+ <em>arguments</em>?.getString(<strong>&quot;username&quot;</strong>)</pre><pre>observeViewModel()<br>}</pre><p>This is how we achieve passing data through a bundle from one fragment to another. However, I’m sure this question must be popping up in your mind that if we can easily pass data through Bundle then why do we need SafeArgs? Why should we use it?</p><p>I agree that we can pass data through Bundle but Sometimes what happens is we try to get data in a destination that has never passed in as extra params of a bundle which causes the null pointer exception in runtime. To avoid this problem, architecture components provide a type-safe way.</p><p>How to use <strong>Safe Arguments for passing data-</strong></p><p>As we have safe args plugin active in our project, let’s see how to use it.</p><p>First, mention the arguments required for the destination in navigation.xml, as shown below:</p><pre><em>&lt;?</em><strong>xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;</strong><em>?&gt;<br></em>&lt;<strong>navigation xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br>    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;<br>    xmlns:tools=&quot;http://schemas.android.com/tools&quot;<br>    android:id=&quot;@+id/navigation&quot;<br>    app:startDestination=&quot;@id/signupFragment&quot;</strong>&gt;</pre><pre>&lt;<strong>fragment<br>        android:id=&quot;@+id/signupFragment&quot;<br>        android:name=&quot;com.navigation.view.SignupFragment&quot;<br>        android:label=&quot;fragment_signup&quot;<br>        tools:layout=&quot;@layout/fragment_signup&quot;</strong>&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToMain&quot;<br>            app:destination=&quot;@id/mainFragment&quot; </strong>/&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToLogin&quot;<br>            app:destination=&quot;@id/loginFragment&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>    &lt;<strong>fragment<br>        android:id=&quot;@+id/mainFragment&quot;<br>        android:name=&quot;com.navigation.view.MainFragment&quot;<br>        android:label=&quot;fragment_main&quot;<br>        tools:layout=&quot;@layout/fragment_main&quot;</strong>&gt;<br>        &lt;<strong>argument<br>           android:name=&quot;username&quot;<br>           app:argType=&quot;string&quot;<br>           android:defaultValue=&quot;default&quot;</strong>/&gt;<br>        &lt;<strong>action<br>            android:id=&quot;@+id/actionGoToSignup&quot;<br>            app:destination=&quot;@id/signupFragment&quot; </strong>/&gt;<br>    &lt;/<strong>fragment</strong>&gt;<br>&lt;/<strong>navigation</strong>&gt;</pre><p>We send data as from source fragment as :</p><pre><strong>super</strong>.onViewCreated(view, savedInstanceState)<br>    signupBtn.setOnClickListener <strong>{ </strong>onSignup() <strong>}</strong><br>}</pre><pre>private fun onSignUp(){<br><strong>val </strong>action = SignupFragmentDirections.actionGoToMain(signupUsername.<em>text</em>.toString())<br>Navigation.findNavController(signupUsername).navigate(action)<br>}</pre><p>Receive data as in destination fragment as:</p><pre><strong>override fun </strong>onViewCreated(view: View, savedInstanceState: Bundle?) {<br>    <strong>super</strong>.onViewCreated(view, savedInstanceState)</pre><pre>signoutBtn.setOnClickListener <strong>{ </strong>onSignout() <strong>}<br>    </strong>deleteUserBtn.setOnClickListener <strong>{ </strong>onDelete() <strong>}<br>    </strong><em><br>    </em>usernameTV.<em>text </em>= <strong>&quot;Hello &quot;</strong>+ MainFragmentArgs.fromBundle(requireArguments()).<strong>username</strong></pre><pre>}</pre><p>Type safe dependency will generate class in the format of <strong>name_of_file_Args </strong>(In our case destination fragment <strong>MainFragmentArgs</strong>) which consists the <strong>&lt;arguments&gt;&lt;/arguments&gt; </strong>in<strong> </strong>navigation file<strong> (navigation).</strong></p><p>Yayyy!! And we are good to go.</p><p>You can also add Actions and Deep Links through the navigation graph.</p><p><strong>Navigation With Deeplink:</strong></p><p>In Android, a deep link is a link that takes you directly to a specific destination within an app. To add deep-link, click on the <strong>+</strong> icon in the <strong>Argument </strong>panel from the <strong>Deep Link </strong>section. In the <em>Add deep link</em> dialog, enter the <em>URI</em>.</p><p>That’s all folks!! Enjoy coding.</p><p>To see the complete project, do visit the GitHub link :</p><p><a href="https://github.com/ashitaasati1608/NaviagtionComponent">https://github.com/ashitaasati1608/NaviagtionComponent</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=89174d51b690" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>