Reader small image

You're reading from  Hands-On Android UI Development

Product typeBook
Published inNov 2017
Reading LevelExpert
PublisherPackt
ISBN-139781788475051
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Jason Morris
Jason Morris
author image
Jason Morris

Jason Morris has been developing software for as long as he can remember. He's written software for the desktop, the server, for feature phones and for smart phones. He's written in many languages, and deployed in a variety of countries. Jason loves a good programming challenge, and when he's not writing code, or spending time with his family, taking photo's or camping: he's probably thinking about programming. In 2010 / 2011 he wrote Android User Interface Development: A Beginners Guide, which helped many beginner Android developers take their first steps into the realm of User Interface design and development for mobile devices.
Read more about Jason Morris

Right arrow

Chapter 5. Binding Data to Widgets

So far, you've been copying the data from your data model into your presentation layer by hand, and then copying it back as well. This shifting data back and forth between stateful widgets is something that you always need to do at some level. Where and how the data is copied can change, but it has to be done to make applications work. In this chapter, we'll look at a system provided by Android called data binding. Data binding provides an alternative to the copying back and forth of data, but also opens several other design opportunities to allow more reuse of code.

Data binding offers you a way to dramatically reduce the amount of boiler-plate code in your application, while remaining type-safe and providing excellent performance. The data binding engine allows you to provide user interface logic that is clearly separated from the layout resources, and can be easily reused by many screens in the application, while reducing the complexity of both the application...

Exploring data models and widgets


In theory, the widgets can directly reference the memory that they are manipulating by holding points to the data, rather than copying the data back and forth, but more often than not, it doesn't make sense to use the same data format for storage and for editing.

Take strings of text for example; the best way to store a string is as a character array; whenever you need to send the text anywhere, over the network or to a display, you can simply read from the first character until the last one, and each one can be transmitted as-is. For example, "Hello World" can be stored as the string length followed by each of the characters:

This is not a good way to store a string that is being edited; however, for editing, it's best to have some buffer space around the cursor to avoid having to copy large amounts of data back and forth as the user types and corrects themselves. For example, if the user places their cursor right after the word "Hello", the same array might...

The Observer pattern


The data binding framework in Android makes use of the Observer pattern to allow for reactive programming. Any object that is referenced by a layout file that implements the Observable interface is watched, and when it signals that it has changed, the user interface updates accordingly. As the data binding system can be used on any attribute or setter of any widget, this means that you can control far more than just the content or state of the user interface. You can control whether widgets are visible or invisible, and you can control which image is used for the background of a widget. At its core, the Observer pattern looks like this:

In the Android Observer pattern, the data model classes expose themselves as Observable by implementing the android.databinding.Observable interface and notifying a list of event-listeners (observers) of any changes to their state. Android provides several convenience classes that make implementing this pattern much easier. There are three...

Enabling data binding


By default in an Android project, the data binding capabilities are turned off. You'll need to enable them in your project's build.gradle file by hand. Follow these quick steps to enable the data binding system:

  1. Start by locating the build.gradle file for your application module in the Android panel in Android Studio:
  1. Open this file and locate the android block:
android {
  compileSdkVersion 26
  // ...
}
  1. At the end of the android block, add the following snippet to enable data binding:
android {
 compileSdkVersion 26
   // ...
   dataBinding {
      enabled = true
   }
}
  1. Once you save this file, Android Studio will open a banner at the top of the file, telling you that it needs to sync the project. Click on the Sync Now link on the right-hand side of the banner and wait for the sync to complete.

Congratulations! You've just enabled the data binding framework on your project. Now you can get started, making use of the data binding system in your layout files, which will simplify...

Data binding a layout file


Data binding works primarily through code generation, and there is very little in the way of runtime overhead. It permits you to use a special expression language in your layout XML files, which gets converted into Java code before your application is compiled. These expressions can call methods, access properties, and are even useful for triggering events. They do have a few restrictions, however: they cannot directly reference the widgets in your user interface, and they cannot create any new objects (they have no new operator). As a result, you'll need to provide your layout files with some utility methods in order to keep things simple, and there are a few guidelines to follow when working with expressions:

  • Keep the expressions simple: Don't write application logic into the expressions; rather, create a utility method that can be reused
  • Avoid manipulating data directly: As tempting as it might be, ensure that your data is always ready for presentation before...

Data binding and fragments


When working with the data binding framework, it's important to put some additional thought into where to encapsulate the various parts of your user interface. As you can hook the logic directly into the layout files, it will often be a better idea to use classes similar to the DatePickerWrapper you wrote in Chapter 3, Taking Actions, with an <include> and <merge> tag, rather that wrapping groups of components in classes. Data-bound layouts that are included in other layouts still have variables, and it's the responsibility of the outer layout to pass those variables downward, into the included layout file. For example, a layout including a date picker might look something like this:

<include layout="@layout/merge_date_picker"
         app:date="@{user.dateOfBirth}"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"/>

As long as either user or its dateOfBirth is Observable, the layout will automatically reflect...

Test your knowledge


  1. Android's data binding framework follows what sort of binding?
    • Model-View View-Model (bidirectional) binding
    • Model-View-Presenter pattern
    • Model-View (unidirectional) binding
  2. Data Bound Layouts have variables that must be which of the following?
    • Any Java Object
    • Observable by the data binding framework
    • Presenter objects
    • Model objects
  1. Which of the following features belongs to data binding expressions?
    • They must be written in single quotes
    • They are Java expressions
    • They are a special expression language
    • They're only evaluated at runtime
  2. To trigger an update of a data-bound user interface, you must do which of these?
    • Listen for object model changes with an event bus
    • Extend the PropertyChangeCallback class
    • Call refresh on the generated Binding object
    • Make a change that the Binding object can observe

Summary


Data binding can not only massively reduce the amount of boilerplate code required to write a user interface, but can actively improve your code base and increase how much code you can reuse. By avoiding complex binding expressions and encapsulating the display logic in your presenter classes, you can build highly modular layouts that are fast, type-safe, and reusable.

It's sometimes useful to think of the data-bound layout files as Java classes in their own right; after all, they will each result in a generated Binding class. It's useful to keep in mind that the Binding classes themselves are also observable, so any changes to them through their generated setter methods will automatically trigger an update in the user interface as well. Also, remember that when you include a data-bound layout in another, you need to pass all of its variables downward, which is just like specifying arguments on a constructor, and those variables don't need to be directly contained within the parent...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Hands-On Android UI Development
Published in: Nov 2017Publisher: PacktISBN-13: 9781788475051
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at £13.99/month. Cancel anytime

Author (1)

author image
Jason Morris

Jason Morris has been developing software for as long as he can remember. He's written software for the desktop, the server, for feature phones and for smart phones. He's written in many languages, and deployed in a variety of countries. Jason loves a good programming challenge, and when he's not writing code, or spending time with his family, taking photo's or camping: he's probably thinking about programming. In 2010 / 2011 he wrote Android User Interface Development: A Beginners Guide, which helped many beginner Android developers take their first steps into the realm of User Interface design and development for mobile devices.
Read more about Jason Morris