<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Samuel Agbesinyale</title>
    <description>The latest articles on Forem by Samuel Agbesinyale (@wilderminds).</description>
    <link>https://forem.com/wilderminds</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F620223%2F53afda79-4335-4956-8e54-ed02585ce9b5.jpg</url>
      <title>Forem: Samuel Agbesinyale</title>
      <link>https://forem.com/wilderminds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wilderminds"/>
    <language>en</language>
    <item>
      <title>How to use Android Studio File Templates to speed up development.</title>
      <dc:creator>Samuel Agbesinyale</dc:creator>
      <pubDate>Thu, 06 May 2021 18:23:04 +0000</pubDate>
      <link>https://forem.com/wilderminds/how-to-use-android-studio-file-templates-to-speed-up-development-4e93</link>
      <guid>https://forem.com/wilderminds/how-to-use-android-studio-file-templates-to-speed-up-development-4e93</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Android Studio comes with a nifty feature that I use quite often to speed 🚀 up my development process.&lt;/p&gt;

&lt;p&gt;Introducing... File Templates🎉.&lt;/p&gt;

&lt;p&gt;We have all used this feature probably without realizing it can help us do much more.&lt;/p&gt;

&lt;p&gt;An instance where we have all utilized file templates is when we right-click on a package in android studio to create a &lt;code&gt;Class&lt;/code&gt;, &lt;code&gt;Enum&lt;/code&gt;, or &lt;code&gt;Interface&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Android Studio allows us to modify these file templates and even lets us create our own.&lt;/p&gt;

&lt;p&gt;Anytime we create a new &lt;code&gt;interface&lt;/code&gt; or &lt;code&gt;class&lt;/code&gt; from the context menu, we are utilizing their respective template files.&lt;/p&gt;

&lt;p&gt;Here's an example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq23ff3orteqqqvabj1pj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq23ff3orteqqqvabj1pj.gif" alt="Creating an Interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The "File and Code Templates" Window.&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Before we begin editing, let's learn how to access the Templates window. There, we can find all existing templates and also create our own.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Right-click on any file/package&lt;/li&gt;
&lt;li&gt;Navigate to "New"&lt;/li&gt;
&lt;li&gt;Click on "Edit File Templates..."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should be presented with a window that looks like this.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p59bbxz93utn15wd3r6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p59bbxz93utn15wd3r6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Note: The Android Studio version being used at the time of writing this article, is v4.1.3&lt;/p&gt;

&lt;h3&gt;
  
  
  Important information&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The template language used is &lt;a href="https://velocity.apache.org/engine/1.7/user-guide.html" rel="noopener noreferrer"&gt;Apache Velocity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When working with File Templates in Android Studio, there are a number of helpful predefined variables which we can utilize to simplify creating or editing template contents.&lt;/p&gt;

&lt;p&gt;Here are some of these predefined variables and what they do: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;${DATE}&lt;/code&gt;&lt;/strong&gt;, returns the current system date&lt;br&gt;
&lt;strong&gt;&lt;code&gt;${TIME}&lt;/code&gt;&lt;/strong&gt;, returns the current system time&lt;br&gt;
&lt;strong&gt;&lt;code&gt;${NAME}&lt;/code&gt;&lt;/strong&gt;, defines the name of the new file (class, interface, enum, etc...)&lt;br&gt;
&lt;strong&gt;&lt;code&gt;${PACKAGE_NAME}&lt;/code&gt;&lt;/strong&gt;, returns the name of the target package in which the new class or interface file is created&lt;br&gt;
&lt;strong&gt;&lt;code&gt;${PROJECT_NAME}&lt;/code&gt;&lt;/strong&gt;, returns the name of the current project&lt;br&gt;
&lt;strong&gt;&lt;code&gt;${USER}&lt;/code&gt;&lt;/strong&gt;, returns the login name of the current user.&lt;/p&gt;

&lt;p&gt;We will take a closer look at how some of these variables are used later on in this article.&lt;/p&gt;

&lt;h6&gt;
  
  
  Understanding the structure and keywords&lt;a&gt;&lt;/a&gt;
&lt;/h6&gt;

&lt;p&gt;Let's take an empty kotlin &lt;code&gt;interface&lt;/code&gt; class for instance.&lt;/p&gt;

&lt;p&gt;This is what it looks like.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.samdev.templates&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MyInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And below is what the &lt;code&gt;Kotlin Interface&lt;/code&gt; template looks like.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;${PACKAGE_NAME}&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File Header.java"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can find the &lt;code&gt;Kotlin Interface&lt;/code&gt; template by scrolling through the list of available templates in the "File and Code Templates" window.&lt;/p&gt;

&lt;p&gt;Now Let's take note of a few things.&lt;br&gt;
1️⃣ The first thing we notice here is how the package name is represented in the template. This is an example of how we use the &lt;code&gt;${PACKAGE_NAME}&lt;/code&gt; variable mentioned earlier.&lt;/p&gt;

&lt;p&gt;2️⃣ The &lt;code&gt;#if&lt;/code&gt; &lt;code&gt;#end&lt;/code&gt; block, which basically ensures the existence of a package name before actually printing it out.&lt;br&gt;
This is necessary so when we create a class in the project root folder, the template engine will skip setting the package name, since none exists at that point.&lt;/p&gt;

&lt;p&gt;3️⃣ The &lt;code&gt;${NAME}&lt;/code&gt; variable which we also mentioned earlier as the variable that is used to define the name of the class. More on this later.&lt;/p&gt;

&lt;p&gt;4️⃣ The &lt;code&gt;#parse&lt;/code&gt; keyword. This script element simply allows us to import a variable or file that contains a template.&lt;br&gt;
Think of this as a "superclass", any templates that exist in the specified file (&lt;code&gt;File Header.java&lt;/code&gt; in our case) will be applied in the template file that references it. Makes sense?&lt;/p&gt;

&lt;p&gt;Let's see the &lt;code&gt;#parse&lt;/code&gt; script element in action.&lt;/p&gt;

&lt;p&gt;The current &lt;code&gt;File Header&lt;/code&gt; template class is empty, so we are going to place some code in there and see how it affects our existing &lt;code&gt;interface&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/**
 * @author ${USER}
 * Created ${DATE} at ${TIME}
 */


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note☝: Any template files we intend to reference with the  &lt;code&gt;#parse&lt;/code&gt; script element, should be created in the "Includes" section of the "File and Code Templates" window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc6jyde5gdqkbt8yj13m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc6jyde5gdqkbt8yj13m.png" alt="The Includes tab in the Templates window "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have already learned what each of the predefined variables &lt;code&gt;${USER}&lt;/code&gt;, &lt;code&gt;${DATE}&lt;/code&gt;, and &lt;code&gt;${TIME}&lt;/code&gt; does (refer to this guy), so let's just take a look at the gif below to see the effect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhalcsgxn4fo0wmis52o5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhalcsgxn4fo0wmis52o5.gif" alt="New interface creation after editing header"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We end up with something like this.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.samdev.templates&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @author samdev
 * Created 06/05/2021 at 1:14 AM
 */&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MyInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will notice that the section that contained the &lt;code&gt;#parse&lt;/code&gt; logic, which was blank before, now contains the result of the header template we added.&lt;/p&gt;

&lt;p&gt;Note☝: We are not bound by predefined variables when editing templates. We can define our own variables using the &lt;a href="https://velocity.apache.org/engine/1.7/user-guide.html#set" rel="noopener noreferrer"&gt;&lt;code&gt;#set&lt;/code&gt;&lt;/a&gt; element, and we can also create variables whose values will be provided via a prompt displayed by Android Studio.&lt;/p&gt;

&lt;p&gt;I will demonstrate this in the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating new templates
&lt;/h3&gt;

&lt;p&gt;To create our own custom templates, we navigate to the "Templates and Code" window by following the steps listed here and tap the '+' icon at the top left corner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dddibn1u5f7okwmlgi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dddibn1u5f7okwmlgi0.png" alt="New template button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are presented with a view where we are required to name the template and also set the extension.&lt;/p&gt;

&lt;p&gt;When writing java templates, we replace the "kt" in the extension field with "java".&lt;/p&gt;

&lt;p&gt;After creating our templates, we can find them in the "New" sub-menu, as indicated below.&lt;/p&gt;

&lt;p&gt;To use them, all we need to do is click, and follow the prompts.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr69ukckmzh7aebbiaa2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr69ukckmzh7aebbiaa2o.png" alt="find_custom_templates"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Now, the reason you are here.
&lt;/h3&gt;

&lt;p&gt;For the purpose of this tutorial, we will be creating 2 templates.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Java Singleton template.&lt;/li&gt;
&lt;li&gt;A Kotlin data access object (Dao) interface template to be used with Room Database.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Java Singleton.
&lt;/h3&gt;

&lt;p&gt;Let's take a look at the actual Singleton class below&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySingleton&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;MySingleton&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;MySingleton&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;MySingleton&lt;/span&gt; &lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MySingleton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MySingleton&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let's take a look at our singleton template.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nn"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File Header.java"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;}()&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;}.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="no"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;}();&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;1️⃣ The first thing we do, just as we have previously indicated, is to set the package name, using the &lt;code&gt;${PACKAGE_NAME}&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;2️⃣ We include any necessary header files using the &lt;code&gt;#parse&lt;/code&gt; script element.&lt;/p&gt;

&lt;p&gt;3️⃣ The &lt;code&gt;${NAME}&lt;/code&gt; variable is used here again.&lt;/p&gt;

&lt;p&gt;Unlike the other variables like &lt;code&gt;${PACKAGE_NAME}&lt;/code&gt;, &lt;code&gt;${DATE}&lt;/code&gt;, etc... the &lt;code&gt;${NAME}&lt;/code&gt; variable obtains its value from user input.&lt;/p&gt;

&lt;p&gt;So how do we set the &lt;code&gt;${NAME}&lt;/code&gt;? The IDE handles that for us, it will display a prompt requesting the Filename.&lt;/p&gt;

&lt;p&gt;Let's see how it works in the gif below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7x0ce58lf7f822tn6gr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7x0ce58lf7f822tn6gr.gif" alt="Java singleton"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After we selected our newly created template named &lt;code&gt;Java Singleton&lt;/code&gt;, we received a prompt, requesting that we enter the "File name". Whatever value we enter in the dialog becomes the value for &lt;code&gt;${NAME}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's it! We have successfully created a java singleton template. Whenever we require a java singleton in our current/future projects, all we need to do is select the template, provide a name, and voila! &lt;/p&gt;

&lt;h3&gt;
  
  
  The Dao Interface class.
&lt;/h3&gt;

&lt;p&gt;When working with Room, we interact with the stored data by defining data access objects. The DAOs include methods that offer abstract access to your app's database.&lt;/p&gt;

&lt;p&gt;Eg: If we have 3 tables/entities, a &lt;code&gt;User&lt;/code&gt; table, &lt;code&gt;Class&lt;/code&gt; table, and a &lt;code&gt;Lesson&lt;/code&gt; table, we are required to create a Dao class for each table so we can access the data in those tables.&lt;/p&gt;

&lt;p&gt;As the number of tables increases, the number of Dao interfaces you have to create also increases.&lt;/p&gt;

&lt;p&gt;In order to make life a little bit easier for us, we can create a Dao Template file, which will be used anytime we need to create new Dao Interfaces. &lt;/p&gt;

&lt;p&gt;Readers who can not familiar with Room and Dao interfaces can refer to this &lt;a href="https://developer.android.com/training/data-storage/room/accessing-data" rel="noopener noreferrer"&gt;link&lt;/a&gt; for clarification.&lt;/p&gt;

&lt;h6&gt;
  
  
  Code Sample
&lt;/h6&gt;

&lt;p&gt;Let's look at a  Dao interface sample for a User entity.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Dao&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserDao&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onConflict&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OnConflictStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;insertAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM user"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM user WHERE id = :id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Delete&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h6&gt;
  
  
  Template
&lt;/h6&gt;

&lt;p&gt;Now let's look at our Dao template&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;PACKAGE_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;${PACKAGE_NAME}&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File Header.java"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.LiveData&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.room.*&lt;/span&gt;

&lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Dao&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onConflict&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OnConflictStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;insertAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;Entity_Class&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM ${Table_Name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;Entity_Class&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM ${Table_Name} WHERE id = :id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;Entity_Class&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="err"&gt;＠&lt;/span&gt;&lt;span class="nc"&gt;Delete&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;Entity_Class&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We have introduced a few new concepts.&lt;/p&gt;

&lt;p&gt;1️⃣ Class imports. You can import and use any existing classes when creating templates as well. &lt;/p&gt;

&lt;p&gt;2️⃣ Custom variables. You will notice that in this template, we are dealing with multiple custom variables, &lt;code&gt;${Entity_Class}&lt;/code&gt; to define our entity data type and &lt;code&gt;${Table_Name}&lt;/code&gt; to define our "table_name"&lt;/p&gt;

&lt;p&gt;Syntax to create a custom variable is &lt;code&gt;${Variable_Name}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The variables get their values the same way the &lt;code&gt;${NAME}&lt;/code&gt; predefined variable gets its value, via the prompt.&lt;/p&gt;

&lt;p&gt;Let's see them in action in the gif below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzkev8a9tpegc6shf7r74.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzkev8a9tpegc6shf7r74.gif" alt="Dao"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Template classes are not that different from your regular java/kotlin classes, so there's so much you can do with them.&lt;/p&gt;

&lt;p&gt;You the next time you need to create a class but already have the template.👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhec8fwym6tpygsawffmj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhec8fwym6tpygsawffmj.gif" alt="goteem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/WilderMinds/d2a7084900c378e525576fb3c748bd2b" rel="noopener noreferrer"&gt;Here&lt;/a&gt; are a few more templates you can take a look at to better understand how they work the extent to which they can be used.&lt;/p&gt;

&lt;p&gt;If you have questions, please leave them in the comments section and I'd do my best to address them! &lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Too many instances of View.setVisibility(...)?</title>
      <dc:creator>Samuel Agbesinyale</dc:creator>
      <pubDate>Mon, 26 Apr 2021 11:16:09 +0000</pubDate>
      <link>https://forem.com/wilderminds/too-many-instances-of-view-setvisibility-42c0</link>
      <guid>https://forem.com/wilderminds/too-many-instances-of-view-setvisibility-42c0</guid>
      <description>&lt;h3&gt;
  
  
  Synopsis
&lt;/h3&gt;

&lt;p&gt;Find yourself "navigating" through multiple views with an inordinate amount of &lt;code&gt;setVisibilty(...)&lt;/code&gt; instances in your code? Here's how to simplify that process and improve the maintainability of your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;I inherited a project a few months back. In this project, a fragment needed to manage several views, but each of these views had too little functionality to warrant creating a separate fragment for each of them.&lt;/p&gt;

&lt;p&gt;The original author, also making the same assertion decided to cycle through the views by controlling their &lt;code&gt;visibility&lt;/code&gt; parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;view1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GONE&lt;/span&gt;
&lt;span class="n"&gt;view2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VISIBLE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You could find several instances of the code above in the fragment class.&lt;/p&gt;

&lt;p&gt;Now, this approach was simple enough and worked, but there were a few issues.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Anytime a new view was added, the navigation logic needed to be updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, as the number of views increased, the code became cluttered pretty quickly because the number of &lt;code&gt;setVisibility()&lt;/code&gt; instances increased.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anytime the user wanted to route back to the previous view, we first had to check which view was currently visible and based on the result, determine which view to display.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;This approach, though not incorrect, made it challenging for another developer to understand the navigation flow. It became even more challenging to make simple changes like adding new views or even altering the existing flow.&lt;/p&gt;

&lt;p&gt;eg: if the initial flow was &lt;br&gt;
view1 -&amp;gt; view2 -&amp;gt; view3&lt;br&gt;
and it became necessary to refactor the order to &lt;br&gt;
view2 -&amp;gt; view1 -&amp;gt; view3&lt;/p&gt;

&lt;p&gt;Such a task required changing multiple sections of the code, which was not ideal.&lt;/p&gt;
&lt;h3&gt;
  
  
  The solution
&lt;/h3&gt;

&lt;p&gt;After spending a few hours trying to understand the navigation flow, the need to refactor became a necessity.&lt;/p&gt;

&lt;p&gt;The first thing to do was to try to get rid of all the &lt;code&gt;setVisibility()&lt;/code&gt; code repetitions, hence the method below.&lt;/p&gt;
&lt;h6&gt;
  
  
  Avoid code repetitions
&lt;/h6&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// outgoing view&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GONE&lt;/span&gt;

    &lt;span class="c1"&gt;// incoming view&lt;/span&gt;
    &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visibility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VISIBLE&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This was great, we could at least get rid of the repeated code by calling the &lt;code&gt;navigate(...)&lt;/code&gt; method above whenever navigation was necessary. But there was still the problem of navigating backward.&lt;/p&gt;

&lt;p&gt;Since we did not want to depend on the view that is currently visible to determine the previous view, we needed a way to keep track of all our view navigations.&lt;/p&gt;
&lt;h6&gt;
  
  
  Tracking navigation history
&lt;/h6&gt;

&lt;p&gt;Let's create a data class that will hold the current view and the next.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;We then employ the use of a &lt;code&gt;Stack()&lt;/code&gt; to preserve the navigation history and update the previous &lt;code&gt;navigate(from: View, to: View)&lt;/code&gt; method to make use of the &lt;code&gt;ViewNavigation&lt;/code&gt; class.&lt;br&gt;
(&lt;em&gt;This process is similar to how a backStack is used for Fragments&lt;/em&gt;)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now let's see how we make use of our newly created &lt;code&gt;navigationStack&lt;/code&gt; to navigate forward and handle back presses.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Each time we call the &lt;code&gt;navigateViews(...)&lt;/code&gt; method we create a &lt;code&gt;ViewNavigation&lt;/code&gt; object and push it onto the stack.&lt;/p&gt;

&lt;h6&gt;
  
  
  Handling back navigations
&lt;/h6&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When attempting to navigate backward, we pop the last item in the stack, as that item represents our most recent navigation.&lt;/p&gt;

&lt;p&gt;As indicated in the comments, we invert the &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt; params when creating a &lt;code&gt;ViewNavigation&lt;/code&gt; object that will be used for navigating in the opposite/reverse direction. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;back()&lt;/code&gt; method returns &lt;code&gt;true&lt;/code&gt; if back navigation was successful and &lt;code&gt;false&lt;/code&gt; if there are no more views left in the stack. When that occurs, we hand over control back to the fragment/activity.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;That's it! We're done. Now, whenever we need to display a particular view, all we need to do is call the &lt;code&gt;CustomNavigator.navigateViews(from: View, to: View)&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;We no longer need to manually check which view is currently displayed before navigating.&lt;/p&gt;

&lt;p&gt;And when new views are added, the navigation logic will not need to be updated!&lt;/p&gt;

&lt;p&gt;Check out the full implementation &lt;a href="https://github.com/WilderMinds/ViewNavigation"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>views</category>
      <category>android</category>
    </item>
  </channel>
</rss>
