Customize the UI of your Button on

Customize the UI of your Button

Note: This document is a work in progress and interfaces here may be subject to change prior to release. It does however accurately reflect the approach to accessing the data that we ourselves use to build Buttons and Commerce Cards.

Dropin Buttons provide a range of visual customization and can accommodate almost all uses. Should you require further flexibility you can access the underlying data that we use to build the Buttons and Commerce Cards as well as being able to invoke cards yourself. This guide will run you through the basics of building your own Button UI.

We'll begin by introducing some concepts and classes that we will use throughout this guide.

App Action

AppAction is the main class that you will use when interacting with Button data. It consists of the objects that make up the Preview and Card which we will discuss in detail later.

Getting an AppAction is simple. Create a context object as you would to populate a Button (outlined here) and call getAction() with your Button ID and a callback handler. You can find your Button ID in the Button Dashboard where you'll also find more Context code samples.

// import com.usebutton.sdk.Button;
// import com.usebutton.sdk.ButtonContext;
// import com.usebutton.sdk.Location;

final Location location = new Location("<#location_name#>", <#latitude#>, <#longitude#>);
final ButtonContext context = ButtonContext.withUserLocation(location);
Button.getButton(this).getAction("<#BUTTON_ID#>", context, new Button.ActionListener() {
    public void onAction(final AppAction action) {


    public void onNoAction() {
        // We had no AppAction available for this context, hide your UI element

Note: The AppAction class and all other classes outlined here implement Parcelable and can be passed as extras in intents. Also, it's important to note that sometimes, there's no inventory available based on the context for the Button. In such cases, we recommend hiding your UI element (see onNoAction in code snippet above).

Key Methods

  • (Preview) getPreview()
  • (void) invoke(Preview)
  • (void) trackButtonView(Context)

Advanced Methods

  • (Header) getHeader()
  • (boolean) hasGroups()
  • (ListBody) getListBody()
  • (boolean) hasProduct()
  • (Product) getProduct()
  • (void) invoke(Context, Inventory)
  • (void) invoke(Context, Fallback)
  • (void) invoke(Context, Product)


The `Preview` object rendered as a button

The Preview object is the first component on the AppAction that you will use. It consists of an icon getIcon() (A in the image above) and a title getText() (B in the image above) and is the object used to populate the default Button in our SDK.

A preview object can have an action getAction() if there's a direct action associated with it, but in most cases the preview itself will not have a default action and you will need to either use an action from one of the Inventory items or use the built-in Commerce Card to allow the user to choose one.

If you use custom cards (see below) and the Preview object has an action you should call AppAction.invoke(Context, Preview) if shouldInvoke() returns true as this means that there's no cards associated with this action and it should be invoked directly.

When you display a Preview to the User, you should report that the action was viewed using the trackButtonViewed (Context) method on the AppAction.

Key Methods

  • (Uri) getIconUri() or (Asset) getIcon()
  • (Text) getTitle() (often NULL for single-line previews)
  • (Text) getText()
  • (boolean) shouldInvoke()

Button Commerce Card

Once you have displayed a preview, you can choose whether to show the underlying inventory or not. If you do want to show the user inventory you can either use the built-in Button Commerce Card or create your own. To make your own, continue reading this guide.

To display the Button Commerce Card for an AppAction you can call AppAction.invoke(Context, Preview) and the user will be presented with the built-in Button Commerce Card and UI flow. A simple way to achieve a custom Button is to render the Preview yourself and to call AppAction.invoke(Context, Preview) from your OnClickListener.onClick(). The remainder of the Button flow will run from that point on (Attended Installation, deep link etc..)

Types of Cards

An AppAction will always have a preview, but from there on things can be a little different. The Card that it's designed to populate will dictate what data is available. For the purposes of this guide, there are two types of Card:

Grouped Inventory Card

AppActions that represent a grouped inventory card will return a ListBody object from getListBody(). This contains the inventory items which are available for this AppAction.

A card representing groups (New York, Boston etc...) and inventory (individual show locations)

The Header A object is available under AppAction.getHeader() and represents a heading describing the inventory.

The ListBody object B, C represents a number of inventory items and a fallback action. The inventory items are individual actions each of which can be invoked by calling AppAction.invoke(Context, Inventory).

The Footer object D can also be invoked with AppAction.invoke(Context, Footer) and is considered as an alternative or fallback action, the inventory items will be more detailed and useful for the user than the footer.


  • (Text) getTitle() A
  • (Text) getSubtitle() A


  • (List<InventoryGroup) getGroups()


  • (Text) getTitle()
  • (Uri) getIconUri()

List Body Items

The ListBody object contains one or more InventoryGroup objects. The InventoryGroups are logical groups B of Inventory items C which we recommend that you reflect in your UI. If AppAction.hasGroups() return we have one or more groups with one or more inventory items.

  • (Text) getName() B
  • (List<Inventory> getInventory()) C

Each group has one or more Inventory items, there's no guarantee to minimum or maximum number of items so your UI should be flexible to handle this. The inventory items can be invoked AppAction.invoke(Context, Inventory), triggering either the action or an app installation that will trigger the action after installation completes.

An inventory item.

When displaying an Inventory item, the following fields are available to you. Calling AppAction.invoke(Context, Inventory) will cause the Button SDK to invoke the action and perform an AttendedInstall if the app is not currently installed.

  • (Text) getPrimary() A
  • (Text) getSecondary() B
  • (Text) getIconText() D
  • (Uri) getIconUri() C

Product Card

Coming soon.

UI Guidelines

Commerce Partners on the Button Marketplace expect that their brand be represented appropriately and within agreed upon guidelines. Before releasing a product using the Custom Button UI, you will need to contact us at to confirm partner approval.

More details on UI Guidelines coming soon.

Visual customization

Buttons are rendered on the fly, but there is still room for customization. Maybe you need to change the size of the icon to match your other icons, or bump the left margin over ever so slightly. You can easily adjust the look of your Button using appearance attributes on the Button view.

Now, for what each of those things means..

Item Appearance Attribute Default Purpose
A android:paddingLeft 3dp Inset all Button content.
B button:btn_iconSize Image size The size of the image on the Button.
A,C,D,E button:btn_drawablePadding 5dp The padding between the image and other elements
A button:btn_drawablePaddingLeft 5dp The padding between the image and other elements, left side
D button:btn_drawablePaddingTop 5dp The padding between the image and other elements, top
C button:btn_drawablePaddingRight 5dp The padding between the image and other elements, right side
E button:btn_drawablePaddingBottom 5dp The padding between the image and other elements, bottom
C button:btn_padding 5dp The padding between the button's outline and its text and icon. You can control the individual paddings with button:btn_paddingLeft, button:btn_paddingTop, button:btn_paddingRight, button:btn_paddingBottom.
D android:paddingTop 5dp Inset all Button content from the top.
E android:paddingBottom 5dp Inset all Button content from the Bottom.
F android:background System default Container view background, can have padding too if e.g. a 9-patch.


You can set any of these on your Button in the layout XML. For a complete list of supported styling attributes, see the documentation for ButtonDropin.