<?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: Enya Emmanuel</title>
    <description>The latest articles on Forem by Enya Emmanuel (@enyason).</description>
    <link>https://forem.com/enyason</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%2F596815%2F0a431177-7ffc-4c15-91e8-408b1dbf0048.jpeg</url>
      <title>Forem: Enya Emmanuel</title>
      <link>https://forem.com/enyason</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/enyason"/>
    <language>en</language>
    <item>
      <title>How to Fix issue of SSL Handshake Exception on Android</title>
      <dc:creator>Enya Emmanuel</dc:creator>
      <pubDate>Thu, 10 Jun 2021 21:58:44 +0000</pubDate>
      <link>https://forem.com/enyason/how-to-fix-issue-of-ssl-handshake-exception-on-android-g6g</link>
      <guid>https://forem.com/enyason/how-to-fix-issue-of-ssl-handshake-exception-on-android-g6g</guid>
      <description>&lt;p&gt;Recently I was working on a chat application for the android platform, everything regarding the remote/networking implementation worked flawlessly. I used the Retrofit networking library and socket.io. At the time, the base url was without SSL (that is the HTTP scheme - &lt;a href="http://api.example.com" rel="noopener noreferrer"&gt;http://api.example.com&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Just before we rolled out the MVP for beta testing, we acquired a domain name and enabled SSL on the server. This meant the base URL scheme became HTTPS (e.g &lt;a href="https://api.example.com" rel="noopener noreferrer"&gt;https://api.example.com&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The change on the app to use a secured URL broke the entire app. All the endpoints were not connecting to the server successfully. Basically the network handshake process between the client and server wasn't successful. Below is what the the error on the log was like&lt;/p&gt;

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

&amp;lt;-- HTTP FAILED: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.


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

&lt;/div&gt;

&lt;p&gt;After doing a little research I discovered it was an issue with the server certificate not being trusted by the android system. This could be because of any of the reasons below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Certificate Authority (CA) that issued the server certificate was unknown.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The server certificate wasn't signed by a CA, but was self signed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The server configuration is missing an intermediate CA.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my case, this issue existed because the server certificate was self signed.&lt;/p&gt;

&lt;p&gt;From android documentation there is a clean way to configure the app to trust your own self-signed certificates, which I will outline in 3 steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Add the crt file to the raw folder.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This file will be retrieved from the server.  You can request for the digital certificate from the backend engineer. It should come in a .crt extension.&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%2F1luv828ildbepq5ost7l.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%2F1luv828ildbepq5ost7l.png" alt="crt file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create an XML network security config file (network_security_config.xml) like below:&lt;/strong&gt;&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%2F2i0nl9473kn4hla3q003.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%2F2i0nl9473kn4hla3q003.png" alt="XML network security config file "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;network_security_config.xml&lt;/code&gt;&lt;/p&gt;


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

&lt;p&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br&gt;
&amp;lt;network-security-config&amp;gt;&lt;br&gt;
    &amp;lt;domain-config&amp;gt;&lt;br&gt;
        &amp;lt;domain includeSubdomains="true"&amp;gt;api.example.com&amp;lt;/domain&amp;gt;&lt;br&gt;
        &amp;lt;trust-anchors&amp;gt;&lt;br&gt;
            &amp;lt;certificates src="@raw/certificate" /&amp;gt;&lt;br&gt;
        &amp;lt;/trust-anchors&amp;gt;&lt;br&gt;
    &amp;lt;/domain-config&amp;gt;&lt;br&gt;
&amp;lt;/network-security-config&amp;gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Step 3&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Specify the network configuration settings in the &lt;code&gt;Manifest.xml&lt;/code&gt; file of your application.&lt;/strong&gt;&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%2Fl43qjdhv0ywgxudkxop8.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%2Fl43qjdhv0ywgxudkxop8.png" alt="android manifest file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With these 3 steps done, you should connect seamlessly with the backend without any further issues.&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to set up a Base Fragment Class with ViewBinding and ViewModel on Android</title>
      <dc:creator>Enya Emmanuel</dc:creator>
      <pubDate>Wed, 07 Apr 2021 07:32:54 +0000</pubDate>
      <link>https://forem.com/enyason/how-to-set-up-a-base-fragment-class-with-viewbinding-and-viewmodel-on-android-57g1</link>
      <guid>https://forem.com/enyason/how-to-set-up-a-base-fragment-class-with-viewbinding-and-viewmodel-on-android-57g1</guid>
      <description>&lt;p&gt;Hey guys! This is my first article on dev.to, and I am super excited about writing again after a long while. Quickly, let's get into the subject at hand.&lt;/p&gt;

&lt;p&gt;Building native Android apps require you have a fair knowledge of object-oriented programming. This forms the basis for this article because we will leverage the concepts of  Inheritance to set up a base class. In addition to this, you’ll learn about generics, with practical examples.&lt;/p&gt;

&lt;p&gt;One may be curious as to why we would want to add another layer of inheritance to our fragment class? This question is usually common with beginner programmers yet to realize the benefits of inheritance.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Inheritance in Object-Oriented Programming (OOP)?
&lt;/h3&gt;

&lt;p&gt;Inheritance is a feature in which a class inherits all the features of another class. The class from which the features are inherited is known as the base class, superclass, or parent class, and the class that inherits the features is known as a derived class, subclass, or child class.&lt;/p&gt;

&lt;p&gt;E.g. If Class D extends A, it is inheriting the features of A.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Generics?
&lt;/h3&gt;

&lt;p&gt;Generics are simply parameterized types. The idea is to allow type (Integer, String, … etc, and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.&lt;/p&gt;

&lt;p&gt;Enough theory, let's get started on creating a base fragment class.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 1:
&lt;/h3&gt;

&lt;p&gt;Create a class BaseFragment that extends a Fragment&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="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseFragment&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VBinding&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewBinding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BaseViewModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;useSharedViewModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getViewModelClass&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ViewModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;VBinding&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getViewBinding&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;VBinding&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;disposableContainer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompositeDisposable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;inflater&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LayoutInflater&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewGroup&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt;
        &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onViewCreated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&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;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onViewCreated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setUpViews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;observeData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;setUpViews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;observeView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;observeData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;binding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getViewBinding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;viewModel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;useSharedViewModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;ViewModelProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;requireActivity&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nf"&gt;getViewModelClass&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;ViewModelProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getViewModelClass&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;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;Disposable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addToContainer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;disposableContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onDestroyView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;disposableContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onDestroyView&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;&lt;code&gt;abstract class BaseFragment&amp;lt;VBinding : ViewBinding, ViewModel : BaseViewModel&amp;gt; : Fragment()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Basically what we've done here is create a &lt;code&gt;BaseFragment&lt;/code&gt; which accepts two types, that is a ViewBinding and a ViewModel. With this class, we move common logic and set up to one place, thereby reducing duplicate codes (boilerplates).&lt;/p&gt;

&lt;p&gt;The ViewModel class and the ViewBinding object specified as fields in the base class will be provided by the subclass when &lt;code&gt;getViewModelClass()&lt;/code&gt; and &lt;code&gt;getViewBinding()&lt;/code&gt; are invoked, respectively.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;open fun setUpViews() {}&lt;/code&gt; and &lt;code&gt;open fun observeData() {}&lt;/code&gt; are methods with a default empty implementation. This makes it optional for its sub-classes to override. The subclasses are not forced to override these methods.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 2:
&lt;/h3&gt;

&lt;p&gt;With the base class set up, we'll use it by creating another fragment class that extends BaseFragment.&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="nd"&gt;@AndroidEntryPoint&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserListFragment&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BaseFragment&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FragmentUserListBinding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;UserViewModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;useSharedViewModel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getViewModelClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UserViewModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getViewBinding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FragmentUserListBinding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layoutInflater&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;setUpViews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// set up recycler view and bind data to UI&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;From the code block above, we have been able to achieve a simple and readable fragment class, using the concepts of inheritance and generics.&lt;/p&gt;

&lt;h3&gt;
  
  
  In summary,
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Using a base fragment helps you avoid code and pattern repetition.&lt;/li&gt;
&lt;li&gt;You achieve a clean and readable code with the concepts discussed in this article.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is it for this article. Please share your thoughts on this subject.&lt;/p&gt;

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