Configuring the Layout of Android’s AlertDialog

Android’s AlertDialog.Builder is a handy little tool to create small dialogs for error messages, warnings, confirmation of delete actions, etc. But when it comes to adapting the layout to the general look and feel of your app there is unfortunately no good documentation available. This article summarizes my findings in this area.

 The structure of the AlertDialog layout

Objects of type AlertDialog are created by calling the create() or show() method of a properly configured AlertDialog.Builder object. There is a version of the constructor for AlertDialog.Builder which has the resource id of an XML style as parameter. Instead of using this parameter you can set the style with

<item name="android:alertDialogTheme">@style/... </item>

in the style file of your app. Some general style properties like windowBackground or dialog style properties like buttonBarStyle can be set this way but there are properties like the background of the message text that cannot be modified this way. To understand why, you have to look at the way an alert dialog constructs its layout:

AlertDialog delegates the job of creating the dialog’s layout to it’s superclass Dialog and to an Android internal class The AlertController class does this by using an XML layout file which is part of the Android SDK (for version 19 you find the different versions under …/platforms/android-19/data/res/values/alert_dialog…) and an XML style that you define in your app theme with

<item name="android:alertDialogStyle">@style/...</item>

Let’s have a look at the layout file first. As an example let’s take the standard holo design of Android SDK version 19 which I have abbreviated for this article:

    <LinearLayout android:id="@+id/topPanel"
        <View android:id="@+id/titleDividerTop"
            android:background="@android:color/holo_blue_light" />
        <LinearLayout android:id="@+id/title_template"
            <ImageView android:id="@+id/icon"
                ... />
            < android:id="@+id/alertTitle"
                ... />
        <View android:id="@+id/titleDivider"
            android:background="@android:color/holo_blue_light" />
    <!-- If the client uses a customTitle, it will be added here. -->
    <LinearLayout android:id="@+id/contentPanel"
        <ScrollView android:id="@+id/scrollView"
            <TextView android:id="@+id/message"
    <LinearLayout android:id="@+id/buttonPanel"
            <Button android:id="@+id/button2"
            <Button android:id="@+id/button3"
            <Button android:id="@+id/button1"
             ... />

As this is a complex structure let’s walk through this top down:

The top structure is a linear, vertically oriented layout that contains three vertically oriented layouts for the title, the message and the button bar.


The linear layout for the title (topPanel) consists of views for the divider lines above (titleDividerTop) and below (titleDivider) the title and a horizontal linear layout (title_template) that contains the icon (icon) and the title text  itself (alertTitle). This is the part of the alert dialog that has the most restrictions:

The design of the divider lines is hard coded in the layout file and can therefore not be changed by a style parameter. Especially the color of the lines (Android’s holo_blue_light) will hurt the overall design of many apps. The only solution here is to adjust the view layout parameter after the AlertDialog has been shown:

// Set title divider color
AlertDialog alert = ... .show();
int titleDividerId = getResources().getIdentifier("titleDivider", "id", "android");
View titleDivider = alert.findViewById(titleDividerId);
if (titleDivider != null)

The test of titleDivider against null is your life insurance against null pointer exceptions in case a new Android version decides to rename or remove the identifier of the title divider view.

The text view for the title itself is a special subclass of TextView called whose only difference to Android’s standard TextView is that it has a special onMeasure() method. Apart from the source code there is no documentation available for this class. As you can see in the layout file you can set a style for this view with a windowTitleStyle item. The text size of the title cannot (!) be set this way as in onMeasure() it is either read from a style file set with the textAppearanceMedium style item or (if this item is not available) from Androids predefined TextAppearance_Medium style.


A standard text message is displayed in a TextView with the id message wrapped within a ScrollView. The TextView reads its style from the textAppearanceMedium style item as well. Therefore you can only set one text size for the title and the text message in your style file for the AlertDialog. If you want different sizes you can do it only programmatically after the AlertDialog has been shown.

Button Bar

The button bar consists of a linear layout with horizontal orientation (id buttonPanel) whose style can be set with a buttonBarStyle style item. It contains three buttons with the ids button2, button3 and button1 (yes, in this order) whose style can be set with buttonBarButtonStyle. In addition to that you can set a divider line on top of the button bar with a dividerHorizontal style item.

Setting the background of the AlertDialog items

AlertDialog leaves as already mentioned most of the layout work to an internal class called Among other things AlertController sets the backgrounds of the different areas of the dialog (title, message, buttons). It does so by reading a bunch of style parameters from a style file that is set with

<item name="android:alertDialogStyle">@style/MepAlertDialogStyle</item>

in the base theme of your app which means in parallel to setting alertDialogTheme (!). The style items look like this:

<style name="MyAlertDialogStyle">
    <item name="android:fullDark">@color/...</item>
    <item name="android:topDark">@color/...</item>
    <item name="android:centerDark">@color/...</item>
    <item name="android:bottomDark">@color/...</item>
    <item name="android:fullBright">@color/...</item>
    <item name="android:topBright">@color/...</item>
    <item name="android:centerBright">@color/...</item>
    <item name="android:bottomBright">@color/...</item>
    <item name="android:bottomMedium">@color/...</item>
    <item name="android:centerMedium">@color/...</item>

The way how AlertController does the background layout of the different views is  a bit complex. The details are only available in the sources of it’s setBackground() method. The general idea is to start with a light or dark background and then iterate between dark and bright when going from top through center to the bottom.

What top, center and bottom (plus “full” under certain circumstances) actually means depends on which views are actually available. For example top will be the title view if it exists. If not it will be the message view. A medium background is (if at all) only used for the button bar. The easiest way to get the style you want is to play a little with the style parameters until you have the backgrounds that you want. The centerMedium parameter that still exists is actually not used anymore by AlertController.

 A boilerplate for an AlertDialog style

The safest way to get a working style is to copy the style elements from one of Android’s standard styles and modify the items to your need. The following boilerplate is based upon the holo light theme of Android platform version 19.

<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
    <item name="android:alertDialogTheme">@style/MyAlertDialogTheme</item>
    <item name="android:alertDialogStyle">@style/MyAlertDialogStyle</item>

<style name="MyBorderlessButton">
    <!-- Set background drawable and text size of the buttons here -->
    <item name="android:background">...</item>
    <item name="android:textSize">...</item>

<style name="MyButtonBar">
    <!-- Define a background for the button bar and a divider between the buttons here -->
    <item name="android:divider">....</item>
    <item name="android:dividerPadding">...</item>
    <item name="android:showDividers">...</item>
    <item name="android:background">...</item>

<style name="MyAlertDialogTitle">
    <item name="android:maxLines">1</item>
    <item name="android:scrollHorizontally">true</item>

<style name="MyAlertTextAppearance">
    <!-- Set text size and color of title and message here -->
    <item name="android:textSize"> ... </item>
    <item name="android:textColor">...</item>

<style name="MepAlertDialogTheme">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowTitleStyle">@style/MyAlertDialogTitle</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
    <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:textAppearanceMedium">@style/MyAlertTextAppearance</item>
    <!-- If you don't want your own button bar style use
    instead of @style/MyButtonBar and @style/MyBorderlessButton
    <item name="android:buttonBarStyle">@style/MyButtonBar</item>
    <item name="android:buttonBarButtonStyle">@style/MyBorderlessButton</item>

<style name="MepAlertDialogStyle">
    <!-- Define background colors of title, message, buttons, etc. here -->
    <item name="android:fullDark">...</item>
    <item name="android:topDark">...</item>
    <item name="android:centerDark">...</item>
    <item name="android:bottomDark">...</item>
    <item name="android:fullBright">...</item>
    <item name="android:topBright">...</item>
    <item name="android:centerBright">...</item>
    <item name="android:bottomBright">...</item>
    <item name="android:bottomMedium">...</item>
    <item name="android:centerMedium">...</item>

Drawing on top of an image in Android’s ImageView

This is a topic for which I found on the Internet a lot of ideas but they were more workarounds for special situations than general solutions.

One of my apps contained an ImageView widget into which I had to load a series of pictures one after the other at runtime. The pictures were of different size, some smaller and some larger than the widget’s size, so the images would either be centered or automatically scaled down by the widget. The challenge was to mark certain areas in the picture with a coloured rectangle dynamically created at run time and adjusted using the coordinates of the original, unscaled image.

The general recommendation on the Internet was to subclass ImageView and overwrite OnDraw with a method that first calls the original OnDraw method of ImageView with the canvas that is provided as parameter to OnDraw and then draws into this canvas on top of the already drawn image.

I am meanwhile quite sure that this works only under certain circumstances, for example when you are sure, your image will not be scaled. The problem lies in the provided canvas. The original onDraw method applies a certain transformation matrix to the canvas before it draws the image into the canvas and restores the canvas in its previous state afterwards. This matrix is stored in a private member variable of ImageView and for whatever reason it is not always the same matrix as the one returned from getImageMatrix() calls. Using the debugger I have seen cases where getImageMatrix returned a non-null matrix where onDraw used a null Matrix and therefore did no do any transformation to the canvas at all. So there is no general reliable way to calculate the coordinates for anything you want to draw on top of what ImageView has drawn.

Therefore I used a different approach:

  1. Create a new image bitmap and attach a brand new canvas to it so that the bitmap and the canvas use the same coordinate system.
  2. Draw the image bitmap into the canvas.
  3. Draw everything else you want into the canvas (the rectangles in my case).
  4. Attach the canvas to the ImageView.

Here is the code snippet:


ImageView myImageView = ...
Bitmap myBitmap = ...
Paint myRectPaint = ...
int x1 = ...
int y1 = ...
int x2 = ...
int y2 = ...

//Create a new image bitmap and attach a brand new canvas to it
Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);

//Draw the image bitmap into the cavas
tempCanvas.drawBitmap(myBitmap, 0, 0, null);

//Draw everything else you want into the canvas, in this example a rectangle with rounded edges
tempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, myPaint);

//Attach the canvas to the ImageView
myImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));

Multidimensional resource arrays in Android

Android allows you to define an XML resource called typed array which defines a list of other other resources (strings, drawables, etc.) whose items can be accessed using an integer index. Unfortunately these items cannot be typed arrays (as there is no method to access this type of item in the TypedArray class), so it is not possible to define multidimensional resource arrays that way.

As a two dimension resource array was exactly what I needed in one of my recent projects and I found a few hints but no good solution on the Internet I had to put something together myself. Here is what I came up with:

I put the array elements in several typed arrays with identifiers ending in ascending numbers:

<?xml version="1.0" encoding="utf-8"?>
   <array name="myArray_0">
   <array name="myArray_1">

That means the array element myArray[x,y] contains the string “string_x_y” and is the y-th element of the typed array resource myArray_x.

For accessing the array elements I used reflection on Android’s R class as this blog post recommended it as the fastest method. Here is the code snippet:

import java.lang.reflect.Field;

Class<R.array> res;
Field field;

int x, y;
String myString;

x = ...
y = ...

try {
   res = R.array.class;
   field = res.getField("myArray_" + new Integer(x).toString());

   //set myString to the string resource myArray[x,y]
   myString = getResources().obtainTypedArray(field.getInt(null)).getString(y);


   catch (Exception e) {

Extracting texts from text frames in Writer using the Java UNO interface

I recently ran into the challenge to use to convert a three digit number of old Microsoft Word documents into simple text files.

Under normal circumstances no big deal: Write a program using the UNO interface to start OpenOffice, load the documents one after the other into OpenOffice Writer (conversion to document format is done automatically) and save the documents as simple text documents.

It was, alas, not that simple. For some reason the texts were contained in text frames which seem to be the only text components that get completely lost when you save an OpenOffice Writer document as a text file. Which meant that I had to write some code to extract the text from the text frames myself.

As I did nowhere find a code snippet for this I thought I post with what I finally came up with. Just in case someone else runs into a similar challenge …

The code assumes you have an object oDocument for the document that contains the text frame for example by using the loadComponentFromURL method of the XComponentLoader interface. One way to accomplish this is explained here.

// Get the list of names of all text frames of the document

XTextFramesSupplier xFrameSupplier = UnoRuntime.queryInterface(XTextFramesSupplier.class, oDocument);
if (xFrameSupplier.getTextFrames().hasElements()){
    String elementNames [] = xFrameSupplier.getTextFrames().getElementNames();

    // Create a text cursor for the first text frame
    // To access the other text frames use elementNames[1], elementNames[2], ...

    Object oTextFrame = xFrameSupplier.getTextFrames().getByName(elementNames[0]);
    XTextFrame xTextFrame = (XTextFrame) UnoRuntime.queryInterface(XTextFrame.class, oTextFrame);
    XText xText=xTextFrame.getText(); 
    XTextCursor xTextCursor = xText.createTextCursor();

    // Extract the text 

    String text = xTextCursor.getString();