Styling

The SDK uses color attributes defined in the ASAPP theme, as well as extra style configuration options set via the style configuration class.

Themes

To customize the SDK theme, extend the default ASAPP theme in your styles.xml file:
<style name="ASAPPTheme.Chat">
   <item name="asapp_primary">@color/custom_asapp_primary</item>
</style>
You must define your color variants for day and night in the appropriate resource files, unless night mode is disabled in your application.
ASAPP recommends starting by only customizing asapp_primary to be your brand’s primary color, and adjusting other colors when necessary for accessibility. asapp_primary is used as the message bubble background in most buttons and other controls. The screenshot below shows the default theme (gray primary - center) and custom primary colors on the left and right.
Customization
There are two other colors you may consider customizing for accessibility or to achieve an exact match with your app’s theme: asapp_on_background and asapp_on_primary. asapp_on_background is used by other elements that might appear in front of the background. asapp_on_primary is used for text and other elements that appear in front of the primary color.

More Colors

Besides the colors used for themes, you can override specific colors in a number of categories: the toolbar, chat content, messages, and other elements. You can override all properties mentioned below in the ASAPPTheme.Chat style. The status bar color is asapp_status_bar and toolbar colors are asapp_toolbar (background), asapp_nav_button, asapp_nav_icon, and asapp_nav_text (foreground).
More Colors
General chat content colors
  • asapp_background
  • asapp_separator_color
  • asapp_control_tint
  • asapp_control_secondary
  • asapp_control_background
  • asapp_success
  • asapp_warning
  • asapp_failure
Message Colors
Message Colors
Message colors
  • asapp_messages_list_background
  • asapp_chat_bubble_sent_text
  • asapp_chat_bubble_sent_bg
  • asapp_chat_bubble_reply_text
  • asapp_chat_bubble_reply_bg
Message Colors

Text and Buttons

To customize fonts and colors for both text and buttons, use the ASAPPCustomTextStyleHandler. To set this optional handler use ASAPPStyleConfig.setTextStyleHandler. Use the given ASAPPTextStyles object to:
  • Set a new font family with updateFonts. If no new fonts are set, the system default will be used instead.
  • Override font sizes, letter spacing, text colors, and text casing styles. You can also customize the font family for each text style individually, if needed.
  • Override button colors for normal, highlighted and disabled states.
Example:
ASAPP.instance.getStyleConfig()
   .setTextStyleHandler { context, textStyles ->
       val regular = Typeface.createFromAsset(context.assets, "fonts/NH-Regular.ttf")
       val medium = Typeface.createFromAsset(context.assets, "fonts/Lato-Bold.ttf")
       val black = Typeface.createFromAsset(context.assets, "fonts/Lato-Black.ttf")
       textStyles.updateFonts(regular, medium, black)
       textStyles.body.fontSize = 14f
       val textHighlightColor = ContextCompat.getColor(context, R.color.my_text_hightlight_color)
       textStyles.primaryButton.textHighlighted = textHighlightColor
   }
See ASAPPTextStyles to see all overridable styles.
setTextStyleHandler is called when an ASAPP activity is created. Use the given Context object if you access resources to make sure that all customization uses correct resource qualifiers.For example: if a user is in chat and toggles Night Mode, the SDK automatically triggers an activity restart. Once the new activity is created, the SDK calls setTextStyleHandler with the new night/day context, which will retrieve the correct color variants from your styles.

Chat Header

The chat header (toolbar in the chat activity) has no content by default, but you can add text or icon using ASAPPStyleConfig.

Text Title

To add text to the chat header, pass a String resource to setChatActivityTitle. By default, the title will be aligned to start. For example:
ASAPP.instance.getStyleConfig()
    .setChatActivityTitle(R.string.asapp_chat_title)
Text Title

Drawable Title

To add an icon to the chat header use: setChatActivityToolbarLogo. You can also center the header content by calling setIsToolbarTitleOrIconCentered(true). For example:
ASAPP.instance.getStyleConfig
    .setChatActivityToolbarLogo(R.drawable.asapp_chat_icon)
    .setIsToolbarTitleOrIconCentered(true)
Drawable Title

Dark Mode

Android 10 (API 29) introduced Dark Mode (a.k.a night mode, dark theme), with a system UI toggle that allows users to switch between light and dark modes. ASAPP recommends reading the developer documentation for more information. The ASAPP SDK theme defines default colors using the system resource “default” and “night” qualifiers, so chat will react to changes to the system night mode setting.
The ASAPP SDK does not automatically convert any color or image assets in Dark Mode, you must define night variants for each custom asset as described in Android >Styling>Theming.
Dark Mode

Disable or Force a Dark Mode Setting

To disable Dark Mode, or to force Dark Mode for Android API levels below 29, ASAPP recommends using the AppCompatDelegate.setDefaultNightMode AndroidX API. This function changes the night mode setting throughout the entire application session, which also includes ASAPP SDK activities. For example, it is possible to use Dark Mode on Android API 21 with the following:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

Atomic Customization

To customize the styles at an atomic level, you can use the setAtomicViewStyleHandler to update viewStyles. Customizing at the atomic level will override any default style that is being set on the UI views. Use it only if general styling is not sufficient, and you need further customization. This is optional, and in most cases, you won’t need it. Use with caution.
ASAPP.instance.getStyleConfig()
    .setAtomicViewStyleHandler { context: Context, viewStyles: ASAPPCustomViewStyles ->
        // Update viewStyles as needed
    }

Custom Theming Example

Following code snippet is an example of how to apply an atomic customized theme.
private fun setCustomStyling() {
        val orangeColor = "#ea7024"
        ASAPP.instance.getStyleConfig(reset = true)
            .setChatActivityToolbarLogo(0)
            .setChatActivityTitle(R.string.asapp_toolbar_custom_title)
            .setIsToolbarTitleOrIconCentered(true)
            .setAtomicViewStyleHandler { context: Context, viewStyles: ASAPPCustomViewStyles ->
                val iconWidthInDp = 24
                val iconWidthInPx = (context.resources.displayMetrics.density * iconWidthInDp).toInt()
                val customRegularTypeface = Typeface.createFromAsset(
                    context.assets,
                    "fonts/Lato-Regular.ttf"
                )
                val customMediumTypeface = Typeface.createFromAsset(
                    context.assets,
                    "fonts/Lato-Medium.ttf"
                )
                val customBoldTypeface = Typeface.createFromAsset(
                    context.assets,
                    "fonts/Lato-Bold.ttf"
                )

                with(viewStyles.connectionBar.success) {
                    container.backgroundColor = Color.GREEN
                    icon.src = R.drawable.nav_check_24px
                    primaryText.color = Color.RED
                    primaryText.typeface = customRegularTypeface
                    icon.src = R.drawable.nav_check_24px
                    icon.tintColor = ContextCompat.getColor(context, R.color.asapp_error_red)
                    icon.width = iconWidthInPx
                }
                with(viewStyles.connectionBar.warn) {
                    container.backgroundColor = Color.YELLOW
                    primaryText.color = Color.WHITE
                    primaryText.typeface = customMediumTypeface
                }
                with(viewStyles.connectionBar.error) {
                    container.backgroundColor = Color.RED
                    icon.src = R.drawable.asapp_img_icon_x
                    primaryText.fontSize = 18f
                    primaryText.typeface = customBoldTypeface
                    icon.tintColor = ContextCompat.getColor(context, R.color.asapp_error_red)
                }
                with(viewStyles.bottomSheetConfirmationDialog) {
                    confirmButtonBar.button.width = MATCH_PARENT
                    cancelButtonBar.button.width = MATCH_PARENT

                    confirmButtonBar.button.radius = Int.MAX_VALUE
                    cancelButtonBar.button.radius = Int.MAX_VALUE

                    confirmButtonBar.button.typeface = Typeface.DEFAULT_BOLD
                    confirmButtonBar.button.textNormal = Color.WHITE
                    confirmButtonBar.button.backgroundNormal = Color.DKGRAY

                    cancelButtonBar.button.typeface = Typeface.DEFAULT_BOLD
                    cancelButtonBar.button.textNormal = Color.DKGRAY
                    cancelButtonBar.button.backgroundNormal = Color.WHITE
                    cancelButtonBar.button.borderNormal = Color.DKGRAY
                }
                with(viewStyles.quickRepliesViewGroup) {
                    container.maxHeight = 600
                }
                viewStyles.titleBar = ASAPPCustomViewStyles.TitleBar.newInstance().apply {
                    primaryText.color = Color.DKGRAY
                    primaryText.fontSize = 14.0f
                    primaryText.typeface = Typeface.DEFAULT
                    icon.width = WRAP_CONTENT
                    actionBackButton.color = Color.parseColor(orangeColor)
                    actionMoreButton.color = Color.parseColor(orangeColor)
                }
                with(viewStyles.ewtBar) {
                    progressBar.visibility = View.VISIBLE
                    progressBar.progressColor = Color.parseColor("#eeeeee")
                    progressBar.backgroundColor = Color.parseColor(orangeColor)
                    btnLeave.textNormal = Color.parseColor("#006fd6")

                    txtEwtTitle.color = Color.DKGRAY
                    txtEwtTitle.fontSize = 16.0f
                    txtEwtValue.color = Color.DKGRAY
                    txtEwtValue.fontSize = 22.0f
                }
                with(viewStyles.chatComposerBar) {
                    btnSend.color = Color.parseColor(orangeColor)
                }
            }
    }

Customization Details

Support for the following customizations are available:

Send Button Color

with(viewStyles.chatComposerBar) {
                    btnSend.color = Color.parseColor(orangeColor)
    }

TitleBar customizations

    viewStyles.titleBar = ASAPPCustomViewStyles.TitleBar.newInstance().apply {
        primaryText.color = Color.DKGRAY
        primaryText.fontSize = 14.0f
        primaryText.typeface = Typeface.DEFAULT
        icon.width = WRAP_CONTENT
        actionBackButton.color = Color.parseColor(orangeColor)
        actionMoreButton.color = Color.parseColor(orangeColor)
    }

Quick Reply Max Height

    with(viewStyles.quickRepliesViewGroup) {
                    container.maxHeight = 600 // Setting the maxHeight to 600 pixel
    }

Estimated Wait Time (EWT) Bar Customization

    with(viewStyles.ewtBar) {
                    progressBar.visibility = View.GONE // Or VISIBLE
                    progressBar.progressColor = Color.parseColor("#eeeeee")
                    progressBar.backgroundColor = Color.parseColor(orangeColor)
                    btnLeave.textNormal = Color.parseColor("#006fd6")

                    txtEwtTitle.color = Color.DKGRAY
                    txtEwtTitle.fontSize = 16.0f
                    txtEwtValue.color = Color.DKGRAY
                    txtEwtValue.fontSize = 22.0f
    }

Connection Status Bar with customized Success/Warning/Error

    with(viewStyles.connectionBar.success) {
        container.backgroundColor = Color.GREEN
        icon.src = R.drawable.nav_check_24px
        primaryText.color = Color.RED
        primaryText.typeface = customRegularTypeface
        icon.src = R.drawable.nav_check_24px
        icon.tintColor = ContextCompat.getColor(context, R.color.asapp_error_red)
        icon.width = iconWidthInPx
    }
    with(viewStyles.connectionBar.warn) {
        container.backgroundColor = Color.YELLOW
        primaryText.color = Color.WHITE
        primaryText.typeface = customMediumTypeface
    }
    with(viewStyles.connectionBar.error) {
        container.backgroundColor = Color.RED
        icon.src = R.drawable.asapp_img_icon_x
        primaryText.fontSize = 18f
        primaryText.typeface = customBoldTypeface
        icon.tintColor = ContextCompat.getColor(context, R.color.asapp_error_red)
    }
    with(viewStyles.bottomSheetConfirmationDialog) {
        confirmButtonBar.button.width = MATCH_PARENT
        cancelButtonBar.button.width = MATCH_PARENT

        confirmButtonBar.button.radius = Int.MAX_VALUE
        cancelButtonBar.button.radius = Int.MAX_VALUE

        confirmButtonBar.button.typeface = Typeface.DEFAULT_BOLD
        confirmButtonBar.button.textNormal = Color.WHITE
        confirmButtonBar.button.backgroundNormal = Color.DKGRAY

        cancelButtonBar.button.typeface = Typeface.DEFAULT_BOLD
        cancelButtonBar.button.textNormal = Color.DKGRAY
        cancelButtonBar.button.backgroundNormal = Color.WHITE
        cancelButtonBar.button.borderNormal = Color.DKGRAY
    }