--- _db_id: 413 available_flavours: - kotlin content_type: project prerequisites: hard: - topics/kotlin/data-binding - topics/kotlin/data-classes - projects/kotlin/project-2/constraint-layout-using-layout-editor soft: [] ready: true submission_type: repo title: Data Binding Basics --- ## App overview In this project, you start with the AboutMe app and change the app to use data binding. The app will look exactly the same when you are done! ##### Here's what the AboutMe app does: - When the user opens the app, the app shows a name, a field to enter a nickname, a Done button, a star image, and scrollable text. - The user can enter a nickname and tap the Done button. The editable field and button are replaced by a text view that shows the entered nickname. **Please use a clone of your app, submit it under this project repo and do not alter the code of the AboutMe project.** ![](8f072e88b4ce64fd.png) ### Task: Use data binding to eliminate findViewById() The code you wrote in previous project uses the `findViewById()` function to obtain references to views. Every time you use `findViewById()` to search for a view after the view is created or recreated, the Android system traverses the view hierarchy at runtime to find it. When your app has only a handful of views, this is not a problem. However, production apps may have dozens of views in a layout, and even with the best design, there will be nested views. Think of a linear layout that contains a scroll view that contains a text view. For a large or deep view hierarchy, finding a view can take enough time that it can noticeably slow down the app for the user. Caching views in variables can help, but you still have to initialize a variable for each view, in each namespace. With lots of views and multiple activities, this adds up, too. One solution is to create an object that contains a reference to each view. This object, called a `Binding` object, can be used by your whole app. This technique is called data _binding_. Once a binding object has been created for your app, you can access the views, and other data, through the binding object, without having to traverse the view hierarchy or search for the data. ![](204bd94c4dd5dd37.jpeg) Data binding has the following benefits: - Code is shorter, easier to read, and easier to maintain than code that uses `findByView()`. - Data and views are clearly separated. This benefit of data binding becomes increasingly important later in this course. - The Android system only traverses the view hierarchy once to get each view, and it happens during app startup, not at runtime when the user is interacting with the app. - You get **type safety** for accessing views. (Type safety means that the compiler validates types while compiling, and it throws an error if you try to assign the wrong type to a variable.) In this task, you set up data binding, and you use data binding to replace calls to `findViewById()` with calls to the binding object. 1 - Clone / Fork (copy) your previous about me project and opened it in Android Studio. 2 - Open the `build.gradle (Module: app)` file. 3 - Inside the `android` section, before the closing brace, add a `dataBinding` section and set `enabled` to `true`. ``` dataBinding { enabled = true } ``` 4 - When prompted, Sync the project. If you're not prompted, select File > Sync Project with Gradle Files. 5 - You can run the app, but you won't see any changes. ### Step 2: Change layout file to be usable with data binding To work with data binding, you need to wrap your XML layout with a `` tag. This is so that the root class is no longer a view group, but is instead a layout that contains view groups and views. The binding object can then know about the layout and the views in it. 1 - Open the `activity_main.xml` file. 2 - Switch to the Text tab. 3 - Add `` as the outermost tag around the ``. ``` ... ``` 4 - Choose Code > Reformat code to fix the code indentation. The namespace declarations for a layout must be in the outermost tag. 5 - Cut the namespace declarations from the `` and paste them into the `` tag. Your opening `` tag should look as shown below, and the `` tag should only contain view properties. ``` ``` 6 - Build and run your app to verify that you did this correctly. ### Step 3: Create a binding object in the main activity Add a reference to the binding object to the main activity, so that you can use it to access views: 1 - Open the `MainActivity.kt` file. 2 - Before `onCreate()`, at the top level, create a variable for the binding object. This variable is customarily called binding. The type of `binding`, the `ActivityMainBinding` class, is created by the compiler specifically for this main activity. The name is derived from the name of the layout file, that is, `activity_main + Binding`. `private lateinit var binding: ActivityMainBinding` 3 - If prompted by Android Studio, import `ActivityMainBinding`. If you aren't prompted, click on `ActivityMainBinding` and press `Alt+Enter` (`Option+Enter` on a Mac) to import this missing class. The `import` statement should look similar to the one shown below. `import com.example.android.aboutme.databinding.ActivityMainBinding` Next, you replace the current `setContentView()` function with an instruction that does the following: - Creates the binding object. - Uses the `setContentView()` function from the `DataBindingUtil` class to associate the `activity_main` layout with the `MainActivity`. This `setContentView()` function also takes care of some data binding setup for the views. 4 - In `onCreate()`, replace the `setContentView()` call with the following line of code. `binding = DataBindingUtil.setContentView(this, R.layout.activity_main)` 5 - Import DataBindingUtil. `import androidx.databinding.DataBindingUtil` ### Step 4: Use the binding object to replace all calls to findViewById() You can now replace all calls to `findViewById()` with references to the views that are in the binding object. When the binding object is created, the compiler generates the names of the views in the binding object from the IDs of the views in the layout, converting them to camel case. So, for example,`done_button` is `doneButton` in the binding object, `nickname_edit` becomes becomes `nicknameEdit`, and `nickname_text` becomes `nicknameText`. 1 - In `onCreate()`, replace the code that uses `findViewById()` to find the `done_button` with code that references the button in the binding object. Replace this code: `findViewById