You probably saw in lots of XML layout examples provided by Google, that sometimes appears the tools namespace. This namespace is useful when developing and doesn’t affect the user experience. Are just a set of handy attributes who help rendering layouts in Android’s Studio Design View.
All this tricky attributes can sometimes save us build time. I’m not saying your build will be faster, but your builds related to UI changes can be fewer.
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent">
The tools namespace full URI is http://schemas.android.com/tools
, usually bound to the tools
prefix but you can use whatever you want.
All this attributes doesn’t impact on runtime or apk size, all tools attributes are stripped by gradle when application is packaged.
You can quickly add the tools namespace with the provided shortcut for Android Studio. Just write toolsNS
and hit TAB
.
Worth mentioning that Android Studio at time of writing this article, doesn’t help too much with the xml syntax completion, so don’t worry, keep writing the tools
override even if AS doesn’t gives you syntax hints. The easiest way to use them is to first write the attributes with the android:
namespace, duplicate the line with CMD + D
and replace the prefix.
Getting started
When i started developing Android, i used to use the android:text=""
attribute with some hardcoded dummy text to see how my TextView or EditText will look on the preview window. But Lint was complaining about hardcoded string and i ended up with defined strings that didn’t deliver nothing to the user and my .apk contained unuseful stuff.
The trick is to use the tools:text="@string"
to see your views pre filled with data on the preview window. You will end up with similar xml:
<TextViewtools:text="Mastering ToolsNs"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
In the above snippet, at design time you will be able to see the TextView
’s text but on runtime that attribute it wont exist.
Different attributes on runtime and design time
Worth note that you can use both android
and tools
namespaces at same time. The tools
namespace will be used at design time and first one at runtime.
Sometimes you want to enable some features on runtime but not on design preview. The Android documentation shows the ListView
example:
<ListViewandroid:id="@+id/listView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:fastScrollAlwaysVisible="true"tools:fastScrollAlwaysVisible=""/>
There you can see that at runtime, the fastScrollAlwaysVisible
is enabled but at design time, is disabled.
Actually you can override any existing attributes from android
namespace but with custom attributes it won’t work.
Target API versions on XML
You can target API levels on XML, in the same way as using @TargetApi
annotation on Java. The API version can be specified by an integer or as codename. This way Lint it won’t complain about version specific XML attributes.
<TextViewtools:text="Mastering ToolsNs"android:layout_width="wrap_content"android:layout_height="wrap_content"tools:layout_height="match_parent"tools:targetApi="M"/>
Tell Lint your string resources are correct
This happens commonly, Android Studio / Lint defaults language is english. If you have for example string resources in other language, it will show some typo warnings as bellow.
The trick is to tell Lint your resources locale:
<resourcesxmlns:tools="http://schemas.android.com/tools"tools:locale="es">
This way it won’t show more typo warnings.
Preview layout on fragment and custom views
I found this specially useful when using Fragment
and Custom Views. With the tools:layout="@layout/your_layout"
you can set a layout to be shown in the preview window.
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"tools:context=".MainActivity"><fragmentandroid:name="com.alexsimo.mastertoolsnamespace.BooksFragment"android:layout_width="match_parent"android:layout_height="wrap_content"tools:layout="@layout/fragment_books"/></LinearLayout>
Above is used the tools:layout
attribute to preview the BooksFragment
layout, without running the project on a device or emulator.
Let’s take this view hierarchy:
activity_main:
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"tools:context=".MainActivity"><fragmentandroid:name="com.alexsimo.mastertoolsnamespace.BooksFragment"android:layout_width="match_parent"android:layout_height="wrap_content"tools:layout="@layout/fragment_book"/></LinearLayout>
fragment_book:
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.RecyclerViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/list"android:name="com.alexsimo.mastertoolsnamespace.BooksFragment"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginLeft="16dp"android:layout_marginRight="16dp"app:layoutManager="LinearLayoutManager"tools:context="com.alexsimo.mastertoolsnamespace.BooksFragment"tools:listitem="@layout/fragment_book_list_item"/>
fragment_book_list_item:
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"xmlns:tools="http://schemas.android.com/tools"><ImageViewandroid:layout_width="150dp"android:layout_height="150dp"android:id="@+id/imageView"tools:src="@android:drawable/ic_media_play"/><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/id"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="@dimen/text_margin"android:textAppearance="?attr/textAppearanceListItem"tools:text="My book title"/><TextViewandroid:id="@+id/content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="@dimen/text_margin"android:textAppearance="?attr/textAppearanceListItem"tools:text="My book description"/></LinearLayout></LinearLayout>
If i open the preview window for activity_main
, i will see the following:
Preview list item’s layout
If you were a bit sharp, in the above xml snippet you saw the tools:listitem=""
line. While previewing a list is useful to see it with your own custom list item and not the default one @android:layout/list_content"
.
There are more related attributes, but as RecyclerView
doesn’t have a header or footer property, can only be used with ListView
. The mentioned attributes are tools:listheader
and tools:listfooter
.
Views with parent context
Imagine you have a custom view or reusable layout that will be used in many other places using <include>
tag. While designing the custom view it may be helpful to preview how it would fit in the parent where is planned to be included.
With the above fragment_book_list_item if we add tools:showIn="@layout/activity_main"
, we can preview how this list item would fit in the activity_main. It doesn’t make lot of sense, but just for demonstrating the concept.
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"xmlns:tools="http://schemas.android.com/tools"tools:showIn="@layout/activity_main"><!-- Remaining views removed --></LinearLayout>
It would be previewed like this:
It also depends on your Android Studio version. At writing the article i’m using Android Studio v2.1.
Associate XML to an Activity
I’m sure this attribute you may already know it, by default when creating an Activity
using Android’s Studio wizard, in the generated XML file you will find this attribute tools:context=".MainActivity"
.
As you may know, a single xml layout can be used by multiple activities or fragments, using this attribute, you tell Android Studio who’s the associated .java
Activity class.
This can help the layout editor to guess the activities theme, since themes are used to be defined in the AndroidManifest.xml
file.
Ignore Lint warnings
You should take special care with this attribute, as ignoring Lint warnings is not always a good idea. If Lint complains, you should act and fix the errors and warnings. But sometimes, Lint gives us false warnings, we are aware and we know what we’re doing (or not..). In those cases you can use tools:ignore=""
.
Imagine we have an icon who’s missing its density folder, we may ignore the Lint warning with tools:ignore="IconMissingDensityFolder"
. You can read more about Lint at official Android’s documentation.
Preview layouts with menus
By default the menu defined in the Activity.onCreateOptionsMenu()
is rendered in the preview window on design mode. But you can override the menu using tools:menu="comma separated menu IDs"
. This attribute, personally i don’t use it, but may be helpful for you.
Set Toolbar navigation mode
This one is short! Using tools:actionBarNavMode="standard|list|tabs"
you can set the ActionBar’s navigation mode.
Shrink resources
There are more android tools namespace attributes related with resources shrinking, like tools:shrinkMode="strict|safe"
, tools:keep="@layout|layout_wildcard"
, tools:discard="@layout/unused"
but i prefer not to talk about them here, since this article is not about shrink resources, if interested you can read more about in Android Studio’s official documentation.