Android Studio comes with a powerful tool that helps you understand how your layout files are going to be rendered on the user's device. As powerful as this tool can be, it can lead to some misleading errors driving the developer crazy. This post talks about how to get the hang of the Preview tool and design layouts that can be grasped at the first glance.

Preview of the Layout Preview screen in Android Studio

The Layout Preview can be accessed by pressing the Preview tab on the right

XML layouts are probably the most frequently used resource in Android development. Chances are you have at least one layout file for every Activity you have in your project. Android Studio's Preview tool helps you implement those great designs and iterate through them quickly without even the need to run your app.

The Layout Preview displays a representation of how your XML code will be displayed on the device. It also allows you to see the different configurations of your layout, such as how would it look like while in portrait or landscape, or how does that TextView look on multiple locales such as English, German or Greek.

When everything works, that is...

Even though the preview tool is powerful and can make your development days a breeze, it can also make your life miserable and frustrating. Unless you know its limitations and how to overcome them, that is!

Here is a list with the most frequently Preview issues I have faced and their solutions for easier development:

Issue #1: The Preview looks empty

Assume you have a layout whose content is to be filled in with data obtained from the backend... You quickly realise that, since the content is dynamic, the Preview tool cannot populate the screen and you see nothing. The naive solution to this issue is to test the layout on-device, where you actually have that data.

Code is there, but Preview shows nothing

The problem in this case is that the TextView and ImageView do not have any content to display. This is a common issue when dealing with dynamic content. Even when the code compiles without issues, no one can make sense of the layout without looking at the XML code.

When creating a layout that uses any content related view, a good practice would be to populate it only while in preview. By using the tools namespace instead of android, while declaring xml attributes, allows you to specify attributes that are going to be used only while in preview. In this case we use tools:text="Title" and tools:src="@drawable/cool_pic" and voilà!

Updated Code and Preview is happy :100:

Attributes declared with the tools prefix work exactly as the android ones but only for preview. This means that your Preview renders the layout with some content which does not get shipped with your app.

What happens though if you don't have images that match the aspect ratio of all ImageViews? You could include some debug resources, which might require some additional effort to make and maintain. Or, you could read Tip #2:

Tip #2: Making dynamic content visible on Preview

When your layout is meant to display some content that comes from an external source, it sometimes helps to have some maximum width or/and height for the parent View. This will ensure that your layout looks good even when the external source sends images that are larger than expected or in some aspect ratio that was not agreed. You can specify the size of your views while in Preview only with tools:layout_height and tools:layout_width. You can use that in combination with tools:background to see how much space those view could take while in preview.

Showing an image without resource

If you are interested in design time configurations, make sure to checkout Sebastiano’s Tools of the trade series.

Tip #3: Fixing broken Previews

When creating a custom View it is important to ensure that your View can be instantiated without using any external dependencies that might not be present while in Preview. Keep in mind that the Preview doesn’t run in your application, but rather on the JVM in the IDE. This will emulate how things work on an Android device, but there’s a lot of shortcuts taken and you should assume you cannot access any number of dependencies that aren’t inside of the View framework. Using an image loader such as Glide, for example, will not be possible. For the same reason, any Dependency Injection framework will not work as it won’t be initialised in the preview context, causing the View to throw an exception while being inflated.
Example of exceptions in preview mode

In this case View.isInEditMode() saves the day. Use it to check whether you are running on the Preview tool and skip any initialisation that requires dependencies that aren’t available at design time:

    public ImageWithCaptionView(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (!isInEditMode()) {

Protip: You can use the tools: namespace to show some default values while in Preview, or have some special handling for the Preview mode within your custom view.

Tip #4: <merge> layout doesn't get rendered

The <merge> tag is a great in helping you reduce duplication of layout code. If you are not using it, make sure to check it out and make your layouts more performant.
The problem with merge, though, is that all the components inside it are going to be collapsed together while displayed in the Preview, creating a visual chaos.

Using merge collapses every view together

The caption is drawn on top of the image

You can use tools:showIn="layout" to display the contents of the <merge> layout inside some other existing layout that uses it. Keep in mind that if you use the same merge layout in multiple places, you can only choose one layout to preview it into.
As of Android Studio 2.2, you can now use the tools:parentTag in order to define the behavior of the <merge> tag for preview purposes. Using tools:parentTag="LinearLayout" for example is going to render the layout as a LinearLayout.

Merge inside some other layout

The caption is drawn below the image as it should 💃

Tip #5: Show hidden Views while in Preview

Your activity might contain some logic that hides some views on creation, but get displayed them after some event. By setting the visibility of those views to gone in your layout, you are ensuring that they are never going to be visible on inflation.

The problem is that these views will disappear from the preview too, and if some other developer opens the layout and looks for them in the preview, they won’t find it. This is a problem because it requires more effort and time to understand what is going on in the screen.

You can yet again use the power of design-time overrides and put a tools:visibility="visible" attribute on the view to show it in the preview panel...

Use this in moderation though. If your layout preview ends up being too different from how the layout will actually look on devices, it can be very confusing. If, for example, you have a bunch of invisible views of which only one at a time can be visible, showing them all in the preview might be chaotic. This might also be an indication you might want to use other lazy-loading mechanisms too, such as inflating only the views you need at runtime...

Those were the most frequent issues I come across when working with the Layout Preview tool in Android Studio. I hope these tips will make your development days easier. Do you use any other nifty tricks to improve the visualization of your layouts? I'd be more than happy to know!

Many thanks to Sebastiano Poggi, Daniele Conti and Daniele Bonaldo for all their help in writing this article.