Adding Tools Attributes to your Toolbox
Android Tools Attributes are a critical element of any well designed app that uses Data Binding, a RecyclerView or top level navigation, such as a Navigation Drawer or Bottom Navigation View. Yet, they are often overlooked by developers.
In this post, we’ll look at why these attributes are important and how you can apply them to provide design-time hints to Android Studio about what type of data and attributes will be applied to your views at runtime.
To illustrate the concepts, we will look at a sample app called Weather. This app displays a list of cities and their current weather forecast summary. Clicking on one of the summary rows, shows a details screen with more information about “today’s” forecast.
The app looks relatively straightforward when you see it running, but how does that look in the Layout Editor at design time. Well that depends!
This project is built using Data Binding and uses a RecyclerView to show the list of cities on the summary screen. If you’re not using tools attributes to give design time hints, it will look something like this…
As you can see, there is no indication of what this view may look like when rendered on a device. It’s hard to even tell what the screens are, let alone:
How will this look on a 5” screen vs a 7” screen?
How does it look in landscape vs portrait?
How does screen density affect the layout?
This becomes even more obvious when you are using the Navigation Architecture Component, where instead of a rich graph showing each of your screens and their relationships to each other:
…you see a bunch of white boxes with no meaning, connected by arrows.
Coming back to the weather app sample. This is a fairly simple app consisting of two screens. So why can’t Android Studio just figure this crap out? 😡
The answer is that Android Studio does not have enough information to figure it out. Data-bound views use binding expressions to describe how to evaluate the contents of the view at runtime. Similarly, RecyclerViews depend on dynamic views being attached at runtime, facilitated by a RecyclerView.Adapter.
At design time, Android Studio has no way of knowing what data will be placed in the views. However, you as the developer do know what types of data will be placed into your views. The tools attributes give you a way to provide hints to Android Studio so that it can render an accurate preview of your views at design time.
Note: Of course things like (the effects of density, orientation, and screen size) are things that you will want to test before shipping your app, but you could get a good idea of how it will render at design time if you use Tools Namespace attributes in your layouts.
The Tools Namespace is an XML namespace that declares attributes you can apply to your views. These attributes give design time rendering hints (such as which item layout to show in a RecyclerView) and designate compile time behaviors (such as specific lint rules to ignore or even specific resources to keep during proguard minification). You are probably already using some of these attributes and may not have noticed.
If you’ve ever suppressed a warning in your layout using the Android Studio quick assist helper, you may notice that it adds a
tools:ignore attribute to the element that was triggering the lint error or warning.
There are 3 categories of attributes:
Error handling attributes – Provide hints to lint, to suppress lint warnings.
Resource shrinking attributes – Provide hints to proguard, to prevent shrinking or removal of specific resources.
Design-time view attributes – Provide hints to Android Studio, so that it can render the view appropriately at design time.
We will focus on the design-time view attributes in this post.
Now, there are dozens of tools attributes ranging from ones that define sample text to show in a text view or a sample image source for an
<ImageView>, all the way to illustrating DrawerLayout states and providing sample data for your RecyclerView. You can find a complete list in the Android Documentation. One good thing to remember though is that any
android attribute associated with the view has a corresponding
A few common examples where
tools attributes can help.
Providing Sample Text
Consider adding a
tools:text attribute for any
android:text attribute that has a binding expression value.
tools:text="Expect a high today of 96, with winds out of the northwest at 21 mph" />
Providing a Sample Image Source
<ImageViews>s where the image is dynamically loaded.
<!-- This example uses a BindingExpression to provide `app:weatherIcon` not shown here -->
Designating a RecyclerView’s Item Layout
tools:listItem to indicate what layout will be inflated and placed into your RecyclerView at runtime.
(This assumes homogeneous item types).
If you really want to be fancy, you can populate lists with sample data, as Thibault de Lambilly shows in his post titled, Android Tools attributes: listItem & sample data rocks!. Although I personally find that providing sample data usually requires more effort to setup and maintain than is worth the effort. Still, if you have a RecyclerView that has vastly different data or you would like to see specific data entries and how they render at design time, you have this as an option.
Improving Weather App
Thanks for reading!