From Punched Cards to Prompts
AndroidIntroduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
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:
Image generated from navigation_graph of the Google Codelabs – Navigation Sample
…you see a bunch of white boxes with no meaning, connected by arrows.
Image generated from navigation_graph of the Google Codelabs – Navigation Sample(With tools layout references removed.)
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 tools
attribute.
A few common examples where tools
attributes can help.
Consider adding a tools:text
attribute for any android:text
attribute that has a binding expression value.
<TextView
...
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{vm.forecast}"
tools:text="Expect a high today of 96, with winds out of the northwest at 21 mph" />
Add a tools:src
inside <ImageViews>
s where the image is dynamically loaded.
<ImageView
android:id="@+id/weather_icon"
android:contentDescription="@{vm.weatherIconContentDesc}"
tools:src="@mipmap/ic_snowy"
app:weatherIcon='@{vm.weatherIcon}' />
<!-- This example uses a BindingExpression to provide `app:weatherIcon` not shown here -->
Use tools:listItem
to indicate what layout will be inflated and placed into your RecyclerView at runtime.
(This assumes homogeneous item types).
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/weather_list_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/weather_item" />
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.
Applying these techniques to Weather App (for the list, details and weather summary item layouts) its navigation graph looks much easier to follow, as can be seen in the diagram below.
CompletedWeatherExample
You can find the sample project for this post in my Github Repo. If you have questions, the best way to reach out to me is on Twitter @emmax.
Thanks for reading!
Introduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
Jetpack Compose is a declarative framework for building native Android UI recommended by Google. To simplify and accelerate UI development, the framework turns the...
Big Nerd Ranch is chock-full of incredibly talented people. Today, we’re starting a series, Tell Our BNR Story, where folks within our industry share...