<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Binding Data - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Binding Data - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 07 Jun 2026 22:34:46 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/binding-data/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Bind Data in Android ]]>
                </title>
                <description>
                    <![CDATA[ Data binding is a technique used when you want to glue pieces of information (your data) to some visual user input elements. In this process, whenever the input gets updated, the data behind it gets updated as well.  This is far from a new concept, a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-bind-data-in-android/</link>
                <guid isPermaLink="false">66ba500643a51af2a76f756b</guid>
                
                    <category>
                        <![CDATA[ Binding Data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tomer ]]>
                </dc:creator>
                <pubDate>Sun, 23 Feb 2020 17:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/02/robert-bye-u2B-xZhoNaE-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Data binding is a technique used when you want to glue pieces of information (your data) to some visual user input elements. In this process, whenever the input gets updated, the data behind it gets updated as well. </p>
<p>This is far from a new concept, and there are a plethora of frameworks that have incorporated this into their design (like AngularJS/React/Vue). </p>
<p>Our attention in this article is not on front-end frameworks but rather on mobile development. Google introduced the <a target="_blank" href="https://developer.android.com/topic/libraries/data-binding">Data Binding Library</a> in Android, which is part of <a target="_blank" href="https://developer.android.com/jetpack">Android Jetpack</a>.</p>
<p>If you are unfamiliar with the Jetpack library suite, it might be because <a target="_blank" href="https://developer.android.com/topic/libraries/support-library">Google has announced</a> that it will be dropping development for its support libraries. Instead, it will move into supporting AndroidX libraries (which are the newer version of the support libraries).</p>
<p>I am aware that there are many articles explaining how to use data binding using an adapter, but this piece won’t focus on that. Instead, I will show a bare-bones, minimal approach to data binding that can save you time by minimizing the amount of code you have to write.</p>
<h1 id="heading-why-use-data-binding">Why Use Data Binding?</h1>
<p>If you aren’t sold yet, let’s take a few minutes to explain the benefit of using data binding by showing an example. Let’s say you have a menu with three custom buttons, where each button is a layout within itself.</p>
<p><img src="https://miro.medium.com/max/438/1*DSKPtz7x8bn2NUVPhdMU4A.png" alt="Image" width="600" height="400" loading="lazy">
<em>Our layout</em></p>
<p>One way to generate all of this is by using four different XML layouts: one for the main layout and one for each of the three buttons.</p>
<p>You need to do this since each button will direct the user to a different part of your application and therefore needs different text and a different image.</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
    <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
    <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>&gt;</span>


    <span class="hljs-tag">&lt;<span class="hljs-name">ImageView</span>
        <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/imageView"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"100dp"</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"100dp"</span>
        <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@drawable/image_name"</span>
        <span class="hljs-attr">android:adjustViewBounds</span>=<span class="hljs-string">"true"</span>
        <span class="hljs-attr">android:scaleType</span>=<span class="hljs-string">"centerInside"</span>
        /&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
        <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/textView"</span>
        <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center_horizontal"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
        <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Image Text"</span>
        <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> /&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">LinearLayout</span>&gt;</span>
</code></pre>
<p>Granted, this isn’t a lot of code duplication as we are only handling three layouts. But if you think about it, it’s quite a waste of time dealing with all that code. If you take into account an application that has a more complicated layout, one that might showcase products and their images, this can lead to a lot of tedious code replication.</p>
<p>With data binding, we will manage to create only one XML layout that will be used by all of our buttons.</p>
<h1 id="heading-where-do-we-start">Where Do We Start?</h1>
<p>We need to let our project enable data binding. For that, we need to add the <code>dataBinding</code> element in our application’s <code>build.gradle</code> file:</p>
<pre><code>android {
    compileSdkVersion <span class="hljs-number">29</span>
    buildToolsVersion <span class="hljs-string">"29.0.2"</span>
    defaultConfig {
        applicationId <span class="hljs-string">"com.tomerpacific.example"</span>
        minSdkVersion <span class="hljs-number">15</span>
        targetSdkVersion <span class="hljs-number">29</span>
        versionCode <span class="hljs-number">1</span>
        versionName <span class="hljs-string">"1.0"</span>
        testInstrumentationRunner <span class="hljs-string">"androidx.test.runner.AndroidJUnitRunner"</span>
        dataBinding {              <span class="hljs-comment">//&lt;-------</span>
          enabled = <span class="hljs-literal">true</span>
        }
    }
    buildTypes {
        release {
            minifyEnabled <span class="hljs-literal">false</span>
            proguardFiles getDefaultProguardFile(<span class="hljs-string">'proguard-android-optimize.txt'</span>), <span class="hljs-string">'proguard-rules.pro'</span>
        }
    }
}
</code></pre><p>After synchronizing our project, we’ll create our data class, which we will use to bind the layout to.</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">package</span> com.tomerpacific.example

<span class="hljs-keyword">import</span> android.graphics.drawable.Drawable

<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ButtonData</span></span>(<span class="hljs-keyword">val</span> buttonText: String, <span class="hljs-keyword">val</span> buttonImageSrc : Drawable)
</code></pre>
<p>Pay attention to the fact that we have two fields in our <code>ButtonData</code> class:</p>
<ul>
<li><code>buttonText</code> — This is the text that will show up beneath our image.</li>
<li><code>buttonImageSrc</code> — This is responsible for the button’s image.</li>
</ul>
<p>If we wanted more data, we would just add more fields to our data class.</p>
<h1 id="heading-the-actual-binding">The Actual Binding</h1>
<p>Next, we need to declare a variable property in our layout so that it can be used. This variable will be bounded to the data class that we created. To do this, there are two things we need to do:</p>
<ul>
<li>Wrap our root layout element in a layout tag.</li>
<li>Add a data tag that will contain the declaration of our variable (<code>buttonData</code>).</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">layout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>&gt;</span>  // <span class="hljs-tag">&lt;<span class="hljs-name">----</span> <span class="hljs-attr">1</span>

    &lt;<span class="hljs-attr">data</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">variable</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"buttonData"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"com.tomerpacific.example.ButtonData"</span>/&gt;</span> // <span class="hljs-tag">&lt;<span class="hljs-name">----</span> <span class="hljs-attr">2</span>
    &lt;/<span class="hljs-attr">data</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">androidx.constraintlayout.widget.ConstraintLayout</span> <span class="hljs-attr">xmlns:app</span>=<span class="hljs-string">"http://schemas.android.com/apk/res-auto"</span>
        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>&gt;</span>


        <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
            <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/textView2"</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Example"</span>
            <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"30dp"</span>
            <span class="hljs-attr">app:layout_constraintLeft_toLeftOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintRight_toRightOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintTop_toTopOf</span>=<span class="hljs-string">"parent"</span> /&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
            <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
            <span class="hljs-attr">app:layout_constraintBottom_toBottomOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintEnd_toStartOf</span>=<span class="hljs-string">"@+id/linearLayout3"</span>
            <span class="hljs-attr">app:layout_constraintStart_toStartOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintTop_toBottomOf</span>=<span class="hljs-string">"@+id/textView2"</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ImageButton</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:adjustViewBounds</span>=<span class="hljs-string">"true"</span>
                <span class="hljs-attr">android:scaleType</span>=<span class="hljs-string">"centerInside"</span>
                <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@drawable/android"</span>&gt;</span>

            <span class="hljs-tag">&lt;/<span class="hljs-name">ImageButton</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
                <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center_horizontal"</span>
                <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Image Text"</span>
                <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> /&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">LinearLayout</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span>
            <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/linearLayout3"</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
            <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
            <span class="hljs-attr">app:layout_constraintBottom_toBottomOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintEnd_toEndOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintStart_toStartOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintTop_toBottomOf</span>=<span class="hljs-string">"@+id/textView2"</span>
            <span class="hljs-attr">app:layout_constraintVertical_bias</span>=<span class="hljs-string">"0.504"</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ImageButton</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:adjustViewBounds</span>=<span class="hljs-string">"true"</span>
                <span class="hljs-attr">android:scaleType</span>=<span class="hljs-string">"centerInside"</span>
                <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@drawable/android_p_logo"</span>&gt;</span>

            <span class="hljs-tag">&lt;/<span class="hljs-name">ImageButton</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
                <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center_horizontal"</span>
                <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Image Text"</span>
                <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> /&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">LinearLayout</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span>
            <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/linearLayout2"</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
            <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
            <span class="hljs-attr">app:layout_constraintBottom_toBottomOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintEnd_toEndOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintHorizontal_bias</span>=<span class="hljs-string">"0.200"</span>
            <span class="hljs-attr">app:layout_constraintStart_toEndOf</span>=<span class="hljs-string">"@+id/linearLayout3"</span>
            <span class="hljs-attr">app:layout_constraintTop_toBottomOf</span>=<span class="hljs-string">"@+id/textView2"</span>
            <span class="hljs-attr">app:layout_constraintVertical_bias</span>=<span class="hljs-string">"0.504"</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ImageButton</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:adjustViewBounds</span>=<span class="hljs-string">"true"</span>
                <span class="hljs-attr">android:scaleType</span>=<span class="hljs-string">"centerInside"</span>
                <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@drawable/android_studio_icon"</span>&gt;</span>

            <span class="hljs-tag">&lt;/<span class="hljs-name">ImageButton</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
                <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center_horizontal"</span>
                <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Image Text"</span>
                <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> /&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">LinearLayout</span>&gt;</span>


    <span class="hljs-tag">&lt;/<span class="hljs-name">androidx.constraintlayout.widget.ConstraintLayout</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">layout</span>&gt;</span>
</code></pre>
<p>Notice that we can remove the schema from our previous main layout as it was moved to the root layout tag. Also, the variable we added is tied directly to our data class.</p>
<p>In our <code>MainActivity</code> file, we need to add code to handle the binding:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">package</span> com.tomerpacific.example

<span class="hljs-keyword">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword">import</span> android.os.Bundle
<span class="hljs-keyword">import</span> androidx.databinding.DataBindingUtil
<span class="hljs-keyword">import</span> com.tomerpacific.example.databinding.ActivityMainBinding

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> : <span class="hljs-type">AppCompatActivity</span></span>() {

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type">Bundle</span>?)</span></span> {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        <span class="hljs-keyword">val</span> binding: ActivityMainBinding = DataBindingUtil.setContentView(
            <span class="hljs-keyword">this</span>, R.layout.activity_main)

        binding.buttonData = ButtonData(<span class="hljs-string">"First"</span>, resources.getDrawable(R.drawable.android))
    }
}
</code></pre>
<p>Each time you create a variable inside of a layout, a binding class is generated for that layout automatically. In our case, our layout is called <code>activity_main</code>, so the binding class will be named <code>ActivityMainBinding</code>.</p>
<p>The convention is always the name of the layout with <em>Binding</em> added at the end.</p>
<p>Since we declared <code>buttonData</code> as our variable in the layout, it gets appended to the binding object and we can assign it a new instance of our <code>ButtonData</code> class.</p>
<p>After doing all that, we can finally use the data that we just bound in our layout.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
            <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
            <span class="hljs-attr">app:layout_constraintBottom_toBottomOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintEnd_toStartOf</span>=<span class="hljs-string">"@+id/linearLayout3"</span>
            <span class="hljs-attr">app:layout_constraintStart_toStartOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintTop_toBottomOf</span>=<span class="hljs-string">"@+id/textView2"</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ImageButton</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:adjustViewBounds</span>=<span class="hljs-string">"true"</span>
                <span class="hljs-attr">android:scaleType</span>=<span class="hljs-string">"centerInside"</span>
                <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@{buttonData.buttonImageSrc}"</span>&gt;</span>  // <span class="hljs-tag">&lt;<span class="hljs-name">----</span>

            &lt;/<span class="hljs-attr">ImageButton</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
                <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center_horizontal"</span>
                <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@{buttonData.buttonText}"</span>   // &lt;<span class="hljs-attr">----</span>
                <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> /&gt;</span>
</code></pre>
<p>And the result is:</p>
<p><img src="https://miro.medium.com/max/438/1*fpchbTcVUnKWKcQQTBvkmg.png" alt="Image" width="600" height="400" loading="lazy">
<em>Pretty smooth, eh?</em></p>
<h1 id="heading-wait-a-second">Wait a Second…</h1>
<p>We have three buttons and our data class can only be used for one button, so how do we get past this?</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">package</span> com.tomerpacific.example

<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ButtonsData</span></span>(<span class="hljs-keyword">val</span> buttonsData : List&lt;ButtonData&gt;) {

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">get</span><span class="hljs-params">(index: <span class="hljs-type">Int</span>)</span></span> : ButtonData {
        <span class="hljs-keyword">return</span> buttonsData.<span class="hljs-keyword">get</span>(index)
    }
}
</code></pre>
<p>We had to override the <code>get</code> method as it needs to be recognized when we use it in our layout.</p>
<p>Then, we need to change the references in our <code>activity_main.xml</code>:</p>
<pre><code class="lang-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">data</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">variable</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"buttonsData"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"com.tomerpacific.example.ButtonsData"</span>/&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">data</span>&gt;</span>
</code></pre>
<p>And we have to create a new binding to the new data class:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type">Bundle</span>?)</span></span> {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        <span class="hljs-keyword">val</span> binding: ActivityMainBinding = DataBindingUtil.setContentView(
            <span class="hljs-keyword">this</span>, R.layout.activity_main)

        <span class="hljs-keyword">val</span> firstButton : ButtonData = ButtonData(<span class="hljs-string">"First"</span>, resources.getDrawable(R.drawable.android))

        <span class="hljs-keyword">val</span> secondButton : ButtonData = ButtonData(<span class="hljs-string">"Second"</span>, resources.getDrawable(R.drawable.android_p_logo))

        <span class="hljs-keyword">val</span> thirdButton : ButtonData = ButtonData(<span class="hljs-string">"Third"</span>, resources.getDrawable(R.drawable.android_studio_icon))

        <span class="hljs-keyword">val</span> buttonsData : ButtonsData = ButtonsData(listOf(firstButton, secondButton, thirdButton))

        binding.buttonsData = buttonsData
    }
</code></pre>
<p>We create three instances of the <code>ButtonData</code> class. Then we instantiate a <code>ButtonsData</code> object and attach it to our binding object.</p>
<p>Lastly, we can now use our data class properly in our layout:</p>
<pre><code class="lang-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span>
            <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
            <span class="hljs-attr">android:layout_gravity</span>=<span class="hljs-string">"center_horizontal"</span>
            <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>
            <span class="hljs-attr">app:layout_constraintBottom_toBottomOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintEnd_toStartOf</span>=<span class="hljs-string">"@+id/linearLayout3"</span>
            <span class="hljs-attr">app:layout_constraintStart_toStartOf</span>=<span class="hljs-string">"parent"</span>
            <span class="hljs-attr">app:layout_constraintTop_toBottomOf</span>=<span class="hljs-string">"@+id/textView2"</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ImageButton</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"100dp"</span>
                <span class="hljs-attr">android:adjustViewBounds</span>=<span class="hljs-string">"true"</span>
                <span class="hljs-attr">android:scaleType</span>=<span class="hljs-string">"centerInside"</span>
                <span class="hljs-attr">android:src</span>=<span class="hljs-string">"@{buttonsData.get(0).buttonImageSrc}"</span>&gt;</span>   // <span class="hljs-tag">&lt;<span class="hljs-name">-------</span>

            &lt;/<span class="hljs-attr">ImageButton</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
                <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>
                <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
                <span class="hljs-attr">android:gravity</span>=<span class="hljs-string">"center_horizontal"</span>
                <span class="hljs-attr">android:text</span>=<span class="hljs-string">"@{buttonsData.get(0).buttonText}"</span>       // &lt;<span class="hljs-attr">--------</span>
                <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> /&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">LinearLayout</span>&gt;</span>
</code></pre>
<p><img src="https://miro.medium.com/max/438/1*IKBNh860MfZ4xj7Og6osKw.png" alt="Image" width="600" height="400" loading="lazy">
<em>Works like a charm</em></p>
<p>This article was written due to my experience developing the following application:</p>
<p>(You never know, it might be useful)</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://play.google.com/store/apps/details?id=com.tomerpacific.laundry">https://play.google.com/store/apps/details?id=com.tomerpacific.laundry</a></div>
<p>You can see the entire source code here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TomerPacific/LaundrySymbols">https://github.com/TomerPacific/LaundrySymbols</a></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Data Binding in Angular Explained ]]>
                </title>
                <description>
                    <![CDATA[ Data Binding Motivation Data often defines the look of an application. Interpreting that data into the user interface involves class logic (.component.ts) and a template view (.component.html). Angular connects them through data binding. Think of dat... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/data-binding-in-angular-explained/</link>
                <guid isPermaLink="false">66c348870bafa8455505c6a0</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Binding Data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 07 Feb 2020 23:19:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9cb2740569d1a4ca33ab.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h1 id="heading-data-binding"><strong>Data Binding</strong></h1>
<h3 id="heading-motivation">Motivation</h3>
<p>Data often defines the look of an application. Interpreting that data into the user interface involves class logic (<code>.component.ts</code>) and a template view (<code>.component.html</code>). Angular connects them through data binding. Think of data binding as a tool for component interaction.</p>
<h3 id="heading-component-and-template">Component and Template</h3>
<p>The component stores most of its logic and data inside of its class decorated with <code>@Component</code>. This decorator defines the class as a component with template HTML. The template of the component represents the class within the application. The focus here needs to be between the component’s class and the template HTML.</p>
<p>This is where data binding occurs. Element properties and events get assigned values. These values, defined by the component class, serve either one of two roles. One is to produce data that the template then receives. The other handles events emitted by the template element.</p>
<p><img src="https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image4.png" alt="Code Example" width="608" height="364" loading="lazy"></p>
<p>Try to use this picture as a mental model for the next section.</p>
<h3 id="heading-directions-of-binding">Directions of Binding</h3>
<p>There are two ways in which data is bound: unidirectional and bidirectional. Angular technically only uses unidirectional data flow. Bidirectional flow is ultimately unidirectional. It happens in two applications of unidirectional flow, once for each direction. More on that later.</p>
<p>Unidirectional flow defines one-way interaction. Either the component sends data to the template or the template emits an event to the component logic. Data changes within scope of the template are not percolate to the component class. Event emitting is a one-way transaction beginning from the template’s elements.</p>
<p>Bidirectional constitutes both directions. This means changes to the data in the class logic or template HTML persist across each other. The scope of the changes are the component’s view. The view comprises the component’s class and template together.</p>
<h3 id="heading-element-properties">Element Properties</h3>
<p>To recognize data-bound element properties, Angular uses a special bracket syntax.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// my.component.ts</span>
<span class="hljs-meta">@Component</span>({
  templateUrl: <span class="hljs-string">'./my.component.html'</span>
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MyComponent {
  value:<span class="hljs-keyword">type</span> = <span class="hljs-comment">/* some value of type */</span>;
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- my.component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">any-element</span> [<span class="hljs-attr">property</span>]=<span class="hljs-string">“value”</span>&gt;</span>innerHTML<span class="hljs-tag">&lt;/<span class="hljs-name">any-element</span>&gt;</span>
</code></pre>
<p>Bear with me on this one.</p>
<p><code>[property]</code> mirrors the property in the Domain Object Model (DOM) element’s object node. Do not confuse object properties with a DOM element’s attributes. Properties and attributes often share the same name and do the same thing. There is one clear distinction however.</p>
<p>Remember that <code>attr</code> (attributes) is a single property of the underlying DOM object. It gets declared at the DOM’s instantiation with attribute values matching the element’s definition. It maintains the same value after that. Properties each have their own key-value field in a DOM object node. These properties are mutable post-instantiation.</p>
<p>Know the difference between attributes and properties. It will lead to a better understanding of how Angular binds data to properties (property binding). Angular will hardly ever bind data to an element’s attributes. Exceptions to this are very rare. One last time: Angular binds component data to properties, not attributes!</p>
<p>Referring back to the example, the <code>[ … ]</code> in the element’s property assignment have special meaning. The brackets show that <code>property</code> is bound to <code>“value”</code> on the right of the assignment.</p>
<p><code>value</code> also has special meaning within context of the brackets. <code>value</code> by itself is a string literal. Angular reads it and matches its value against component class members. Angular will substitute the value of the matching member attribute. This of course refers to the same component class that hosts the template HTML.</p>
<p>The unidirectional flow of data from component to template is complete. The member matched against right assignment of the bracketed property provides the <code>value</code>. Note that changes to the member’s value in the component class percolate down to the template. That is Angular’s change detection at work. Changes within the template’s scope have no effect on the component class member.</p>
<p>Key take-away: the component class provides the data while the template displays it.</p>
<p>I failed to mention that data values can also show up in a component’s <code>innerHTML</code>. This last example implements double curly braces. Angular recognizes these braces and interpolates the matching component class data into the <code>innerHTML</code> of the <code>div</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>The value of the component class member ‘value’ is {{value}}.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-event-handling">Event Handling</h3>
<p>If the component supplies data, then the template supplies events.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// my.component.ts</span>
<span class="hljs-meta">@Component</span>({
  templateUrl: <span class="hljs-string">'./my.component.html'</span>
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MyComponent {
  handler(event):<span class="hljs-built_in">void</span> {
      <span class="hljs-comment">// function does stuff</span>
  }
}
</code></pre>
<pre><code class="lang-html">// my.component.html
<span class="hljs-tag">&lt;<span class="hljs-name">any-element</span> (<span class="hljs-attr">event</span>)=<span class="hljs-string">“handler($event)”</span>&gt;</span>innerHTML<span class="hljs-tag">&lt;/<span class="hljs-name">any-element</span>&gt;</span>
</code></pre>
<p>This works similarly to property binding.</p>
<p>The <code>(event)</code> pertains to any valid event type. For example, one of the most common event types is <code>click</code>. It emits when you <em>click</em> your mouse. Regardless of the type, <code>event</code> is bound to <code>“handler”</code> in the example. Event handlers are usually member functions of the component class.</p>
<p>The <code>( … )</code> are special to Angular. Parenthesis tell Angular an event is bounded to the right assignment of <code>handler</code>. The event itself originates from the host element.</p>
<p>When the event does emit, it passes the Event object in the form of <code>$event</code>. The <code>handler</code> maps to the identically named <code>handler</code> function of the component class. The unidirectional exchange from the event-bound element to the component class is complete.</p>
<p>Emitting events from the handler, while possible, do not impact the template element. The binding is unidirectional after all.</p>
<h3 id="heading-bidirectional-binding">Bidirectional Binding</h3>
<p>Input forms provide a great example of why bidirectional binding is necessary. Bidirectional data bindings are more costly than event or property bindings.</p>
<p>Bidirectional data binding has its own module. Before taking a look at that, consider the following example.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// my.component.ts</span>
<span class="hljs-meta">@Component</span>({
  templateUrl: <span class="hljs-string">'./my.component.html'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MyComponent {
  inputValue:<span class="hljs-built_in">string</span> = <span class="hljs-string">""</span>;

  handler(event) {
      <span class="hljs-built_in">this</span>.inputValue = event.target.value;
  }
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- my.component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> (<span class="hljs-attr">input</span>)=<span class="hljs-string">“handler($event)”</span> [<span class="hljs-attr">value</span>]=<span class="hljs-string">“inputValue”</span>&gt;</span>
</code></pre>
<p>Time to break this down.</p>
<p>This example combines the previous two. That explains why it is more costly. Following the logic, assume the user types something into the input element. The element emits an <code>input</code> event to the <code>handler</code> of the template’s component class. The handler assigns the class member <code>inputValue</code> to the value of the emitted event. This concludes the event handling/binding.</p>
<p>Now onto the property binding. The <code>inputValue</code> was assigned a new value. Since <code>inputValue</code> is bound to the input element’s <code>value</code>, its change in data percolates down into the input element’s <code>value</code> property. The input element’s <code>value</code> matches up with <code>inputValue</code>. This concludes the property binding.</p>
<p>There you have it. Bidirectional data binding happens with both applications of unidirectional binding applied consecutively. The syntax is a bit messy though.</p>
<p>Thankfully, Angular provides <code>NgModel</code> to simplify the syntax. The below example is synonymous to the above.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// my.component.ts</span>
<span class="hljs-meta">@Component</span>({
  templateUrl: ‘./my.component.html’
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MyComponent {
  inputValue:<span class="hljs-built_in">string</span> = <span class="hljs-string">""</span>;
}
</code></pre>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- my.component.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> [(<span class="hljs-attr">ngModel</span>)]=<span class="hljs-string">“inputValue”</span>&gt;</span>
</code></pre>
<p><code>ngModel</code> is a nice convenience. You have to import the FormsModule in your application’s root before using it. With that squared away, bidirectional data binding becomes much easier to work with.</p>
<p>To reinforce all you have learned, check out this picture from the official <a target="_blank" href="https://angular.io/guide/architecture-components#data-binding">Angular Documentation<sup>1</sup></a>.</p>
<p><img src="https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image2.png" alt="Data Flow Diagram" width="220" height="205" loading="lazy"></p>
<p>You can visually summarize everything up until this point with this picture. Angular’s Documentation has plenty of other pictures worth seeing. This one should suffice given the scope of this article.</p>
<h3 id="heading-component-to-component">Component to Component</h3>
<p>To bind data and events across different components, you must use the @Input and @Output decorators. Angular components are privately scoped. None of a component’s members are accessible from anywhere outside of its native view.</p>
<p>The @Input decorator indicates a member’s value is sourced from the parent function. This requires visualization to better understand.</p>
<p><img src="https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image3_.png" alt="Code Example" width="624" height="468" loading="lazy"></p>
<p>Notice the passing of the parent’s <code>value</code> member into the child’s <code>property</code> member. This would not be possible if <code>property</code> had no @Input decorator. The Angular compiler depends upon it.</p>
<p>Another example for @Output shows how an event travels from child to parent. Keep in mind that @Output almost always pertains to custom event bindings.</p>
<p><img src="https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image1.png" alt="Code Example" width="624" height="468" loading="lazy"></p>
<p>Make sure you import <code>EventEmitter</code>, <code>@Input</code>, and <code>@Output</code> from <code>@angular/common</code> if you intend to replicate either of these examples.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This is a good place to stop. Data binding spans a wide array of use cases. This topic is worth exploring further on <a target="_blank" href="https://angular.io/">Angular’s website</a>. These are not the only ways that you can manipulate data in Angular. See the links under Resources for more information.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
