Uh oh! We couldn’t find any match.

Please try other search keywords.

Bixby Developer Center

Guides

Creating Bixby Views

Bixby lets you construct views to build your capsule's user interface. Bixby Views uses the same key-value modeling language that Bixby's models are defined in. By using them, you can create interactive designs for Bixby in a simple, consistent manner. Views render the content of Moments in Bixby's conversation model.

There are three view types:

  • Result views define the layout used for results returned from Bixby.
  • Confirmation views are shown when Bixby is about to execute an action that requires user approval/review before proceeding.
  • Input views contain buttons, fields, and other input elements that allow users to give Bixby information.

View definitions start with a render block. Within render blocks, you'll find either input components for user input, or layouts which describe the contents of result views and confirmation views. A layout is built out of layout components. Components include text, images, titles, sections, and even maps and image carousels. Building a layout in Bixby Views is similar to building a web page, but views have a more clearly defined hierarchy: some components are containers for other components, but not every kind of component is valid within a given kind of container. For more about input components, which do not use layouts, read about input views.

View files, including layouts and layout macros, belong under your capsule's /resources/ folder, either in /resources/base/ or in subfolders for device targets and locales if appropriate. A good practice is to put them in a layouts/ subfolder, and optionally use subfolders within layouts/ if you want further organization.

Note

For more information about individual components used in each view, see the appropriate reference pages for each view and each component. You can also play with the Bixby Views sample capsule and the Input Forms sample capsule to see these views, and the subsequent layouts and layout-macros in action. All the examples below use the Space Resorts Walkthrough sample capsule unless noted otherwise.

View Basics

A Simple Layout

To learn about Bixby Views, let's look at the result view from the Dice capsule you built in the Quick Start Guide. This file is in the resources/ folder, and by convention is named after the concept it matches on: RollResult.view.bxb.

result-view {
match {
RollResultConcept (rollResult)
}

render {
layout {
section {
content {
single-line {
text {
style (Detail_M)
value ("Sum: #{value(rollResult.sum)}")
}
}
single-line {
text {
style (Detail_M)
value ("Rolls: #{value(rollResult.roll)}")
}
}
}
}
}
}
}

This view uses a match pattern to associate it with the concept RollResultConcept. When the output to be displayed to the user is a RollResultConcept, this view will be used to display it.

The view itself is defined in the layout block. This layout has a single section, which in turn contains a content block with two single-line elements, each with a style (in this case, both are Detail_M) and value. This creates a simple nested hierarchy:

  • Layout
    • Section
      • Content
        • Single Line
          • Text ("Sum: ...")
        • Single Line
          • Text ("Rolls: ...")

Bixby Views are similar to HTML documents in this way: blocks nested within blocks. Instead of using tags like <section> and <p>, views just use Bixby keys like section and text.

Let's spruce Dice's output up a little with some graphics. Add an image block right under the content key:

content {
image {
url (https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Double-six-dice.jpg/1200px-Double-six-dice.jpg)
}
// single-line { ...
}

Now, when you roll some dice, you'll see an image!

Dice capsule with image

Reusable Layouts with Macros

Sometimes you might create a complex layout that you want to use in more than one view. For instance, a layout that shows details of a hotel or a restaurant could be shown in a list of search results as well as used on a page for making a reservation. Bixby Views lets you re-use partial layouts with Layout Macros. Here's a quick overview.

Let's say you wanted to turn the result view from Dice into a macro. You'd define it with a layout-macro-def block. This block would be part of a *.layout.bxb folder in the appropriate locale-specific folder under resources/; while it could be in its own file, you can have multiple macros in one file.

layout-macro-def (roll-results) {
params {
param (rollResult)
type (RollResultConcept)
min (Required) max (One)
}
content {
section {
content {
single-line {
text {
style (Detail_M)
value ("Sum: #{value(rollResult.sum)}")
}
}
single-line {
text {
style (Detail_M)
value ("Rolls: #{value(rollResult.roll)}")
}
}
}
}
}
}

This begins with a parameter list (params), which defines parameters for the macro. In this case, we need to be able to display the contents of a RollResultConcept. The param block works a lot like the match block in the original view, binding the value of a RollResultConcept to rollResult for use later. The render block is replaced with a content block that defines the layout macro's content.

With this macro defined, our original result view for Dice now looks like this:

result-view {
match {
RollResultConcept (rollResult)
}

render {
layout-macro (roll-results) {
param (rollResult) {
expression (rollResult)
}
}
}
}

For extensive coverage of layout macros, read the Layout Macros documentation.

Displaying Lists

Unlike HTML, Bixby Views can contain conditionals and control flow commands. The for-each loop is particularly useful, iterating through an array of structures to render each element in a separate view component. You could also use if-else blocks to selectively render elements.

Here's an example that uses both of those techniques. It's a simplified version of a layout that appears in the ScoreBook.layout.bxb file from the Quiz template.

result-view {
match {
ScoreBook (scoreBook)
}
render {
layout {
section {
content {
for-each (scoreBook.scores) {
as (score) {
text {
style (Detail_M)
value ("Question: #{value(score.question.textToDisplay)}")
}
image {
url {
if (score.evaluation == true) {
template ("/icons/correct.png")
} else {
template ("/icons/incorrect.png")
}
}
}
divider
}
}
}
}
}
}
}

This uses a for-each loop to loop through each score value, which is an array in scoreBook.scores. A different icon is shown for correct and incorrect answers, chosen using an if-else block. (The if-else block will evaluate to one of the two specified template values, and that will be used as the value for url.)

A result view can also use the list-of key to render a list. This is a similar looping construct; read its reference page for more details and a complete example from Space Resorts.

Result Views

The views we've been describing above are all result views. Result views let you build displays for search results, individual detail pages, image carousels, and more. A result view can also directly launch an outside application. They're what Bixby displays during a Result Moment.

We've seen some simpler result views above. This is an example of a more complicated view from the Space Resorts capsule. It shows information about a single resort, and uses a layout macro to include both an image carousel and a detail view:

result-view {
match: SpaceResort (result) {
min (Required) max (One)
}

render {
layout {
layout-macro (space-resort-image-carousel) {
param (spaceResort) {
expression (result)
}
}
layout-macro (space-resort-details) {
param (spaceResort) {
expression (result)
}
}
}
}
conversation-drivers {
conversation-driver {
template ("Make Reservation")
}
}
}

This is an example of what would display:

Result view with one result

Here's the layout macro definition being used in the above view.

layout-macro-def (space-resort-details) {
params {
param (spaceResort) {
type (SpaceResort)
min (Required) max (One)
}
}
content {
section {
title {
template ("#{value(spaceResort.name)}")
}
content {
single-line {
text {
value ("#{value(spaceResort.planet)} • #{value(spaceResort.gravity)}g")
style (Detail_M)
}
}
paragraph {
value ("#{value(spaceResort.description)}")
style (Detail_M)
}
}
}
}
}

This layout-macro corresponds to this part of the result view rendered above:

Result View - Space Resort Details

A result-view can have the following components in its render block:

Note

The number of items that returns should dictate what you render. For zero results, use nothing or a layout. For a single result, use the Details mode or call the detailed layout-macro for that item. For multiple results, use list-of or image-list-of.

If you need the user to be taken to an outside application, Bixby can directly launch that application with the result-view. You should only punch out to an app in the situations outlined in the App Punch Out Policies.

Confirmation Views

Confirmation views let you build user interfaces for reviewing and confirming actions during a Confirmation Moment. These views should only be used in a transactional workflow.

As with result views, confirmation views can use layouts and layout-macros. In addition, confirmation views can use transaction properties in their layouts.

Here is the confirmation view for the space resort capsule, which confirms the order:

// resources/base/layouts/Order/Confirmation.view.bxb
confirmation-view {
match {
Confirmation {
confirming {
MakeReservation (action)
}
}
}

message {
template-macro (COMMIT_ORDER_CONFIRMATION)
}

mode (PositiveEmphasis)

// Confirming with a `value: Confirmation(true)` doesn't work without this block. DO NOT remove confirm-options.
confirm-options {
on-confirm {
if (false) {
halt {
dialog ("")
}
}
}
}

render {
layout {
layout-macro (order-image-card) {
param (order) {
expression (action.order)
}
}
layout-macro (order-details) {
param (order) {
expression (action.order)
}
}
if (exists(action.order.buyer)) {
layout-macro (order-contact-information) {
param (order) {
expression (action.order)
}
}
}
}
}
}

Here is an example of what might display:

Confirmation View

The render block of a confirmation-view can only include layouts:

  • A layout can be directly included in the render block with layout
  • A layout can be defined in an external file with layout-match or layout-macro can be defined in an external layout.bxb file

If you are confirming a transaction and need to verify payment from a user, you should use a payment-selection component.

Note

Input Views

Input views let your capsule gather information from the user during an Input Moment. Unlike result and confirmation views, input views do not use layouts in their render blocks. Instead, they use their own set of input components. Input components allow users to easily pick time, date, images, and find information with the aid of auto-complete. You can also use components to create forms with text and numbers.

Here is an example of an input component that allows the user to make a single selection from a list:

Screenshot of Single Select Picker

An input-view must include a match block that defines the data this view is for: in this case, picking the checkout date. The render block renders the view, using a calendar component.

The keys in the render block of an input-view include components for pickers, auto-complete (search fields), and forms:

  • date-picker: lets users select a date
  • time-picker: lets users select a time
  • calendar: lets users select a date or date range from a calendar
  • image-picker: lets users select one or more images
  • selection-of: lets users choose one or more items from a given list
  • auto-complete: presents a search field with completion suggestions from a given list
  • form: generates a view with editable fields for users to input information

For complete documentation about input components, consult the reference page for that particular component.

Here is an example input-view you might use to get reservation dates using a calendar:

input-view {
match: DateInterval (this)
render {
calendar {
allow-range (true)
restrictions {
block-past-dates (true)
}
}
}
}

Here is what would display:

Input View, using a calendar

Default Views

If you do not specify a result-view or an input-view that matches the current moment, Bixby uses a default view that can provide a reasonable display of results or selectable options to the user. Your capsule should provide its own views for the best possible conversations with users. Read Bixby's Design Guides for guidance.

There is no default confirmation-view, although Bixby falls back to default confirmation dialog and displays if views are not defined for confirmation moments.

Default result-view

result-view {
match: _ (this)

message {
if (size(this) == 0) {
template ("#{event(this, 'NoResult')}")
} else {
template ("#{event(this, 'Result')}")
}
}

render {
if (size(this) == 0) {
nothing
} else-if (size(this) == 1) {
layout-match(this) {
mode (Details)
}
} else {
list-of (this) {
navigation-mode {
read-many {
page-size (size(this))
page-content {
underflow-statement ()
overflow-statement ()
}
}
}

where-each (item) {
layout-match (item) {
mode (Summary)
}
}
}
}
}
}

Default input-view

input-view {
  match: _ (this)

  message {
    if (size(this) == 0) {
      template ("#{event(this, 'Elicitation')}")
    } else {
      template ("#{event(this, 'Selection')}")
    }
  }

  render {
    if (size(this) > 0) {
      selection-of (this) {
        navigation-mode {
          read-many {
            page-size (size(this))
            page-content {
              item-selection-question()
              underflow-statement ()
              overflow-statement ()
            }
          }
        }

        where-each (item) {
          layout-match (item) {
            mode (Summary)
          }
        }
      }
    }
  }
}