Theme and Style¶
Introduction¶
An enterprise usually has its own branding theme when developing a mobile app and it is therefore desirable to allow the onboarding screens to have the same look and feel as the other branded screens in the mobile app.
SAP BTP SDK for Android version 3.4 and higher provides an improved method for customizing the onboarding theme and style in the client code. With this improvement, it's easier to:
- Define the logo image, as well as its height and width.
- Customize all the buttons used in the onboarding screens.
- Customize all the text input fields used in the onboarding screens.
- Customize all text appearances.
- Customize other UI elements, such as the avatar in the Sign In screen, for example.
Here are some example Sign In screens:
To achieve this goal, we extracted the styles used in the onboarding screens into theme attributes and put them into FioriTheme.Onboarding
.
<style name="FioriTheme.Onboarding" parent="Onboarding.Default.Light.Theme">
<!-- Onboarding button -->
<item name="onboarding_button_raised_ref">@style/Widget.Onboarding.Button</item>
<item name="onboarding_button_raised_background_pressed">
@color/onboarding_button_raised_background_pressed
</item>
<item name="onboarding_button_raised_background_disabled">
@color/onboarding_button_raised_background_disabled
</item>
<item name="onboarding_button_raised_background">
@color/onboarding_button_raised_background
</item>
<item name="onboarding_button_raised_text_disabled">
@color/onboarding_button_raised_text_disabled
</item>
<item name="onboarding_button_raised_text">@color/sap_raised_button_text_color</item>
<item name="onboarding_button_raised_text_disabled">
@color/onboarding_button_raised_text_disabled
</item>
...
In this theme definition, we can see that for the raised buttons used in the onboarding screens, the client code can either define onboarding_button_raised_ref
to define the whole style for the raised buttons, or only provide some style properties, for example, onboarding_button_raised_background
, to customize the raised button background color.
For other UI elements, we're using the same approach to let the client code customize the styles.
Logo¶
To change the logo image on each onboarding screen at the top, define the following style in styles.xml
.
<style name="OnboardingLogo">
<!-- The value is always @drawable/<your_logo_name_without_ext> -->
<!-- Do not add the file extension e.g. .png -->
<item name="android:src">@drawable/custom_logo</item>
<item name="android:layout_height">72dp</item>
<item name="android:layout_width">72dp</item>
</style>
In addition to android:src
of the logo image, you can also customize the height and width for different logo image sizes.
Raised and Flat Buttons¶
<!-- onboarding flat button -->
<item name="onboarding_button_flat_ref">@style/Widget.Onboarding.Button.Borderless</item>
<item name="onboarding_button_flat_text">@color/sap_ui_flat_button_text_color</item>
<item name="onboarding_button_flat_text_disabled">
@color/onboarding_button_flat_text_disabled
</item>
<item name="onboarding_button_flat_background_pressed">
@color/onboarding_button_flat_background_pressed
</item>
<item name="onboarding_button_flat_background_disabled">
@color/onboarding_button_flat_background_disabled
</item>
<item name="onboarding_button_flat_background">
@color/onboarding_button_flat_background
</item>
While the preceding code illustrates the theme attributes for flat buttons, both raised and flat button styles can be fully customized by specifying onboarding_button_flat_ref
and onboarding_button_raised_ref
in the client code. The client code can also define the button background color and text color for different states.
Text Input Fields¶
The onboarding screens use the Fiori widget, SimplePropertyFormCell
, for the text input fields. For example, the user name and passcode input fields on the Sign In screen. The client code can implement the fully customized style for SimplePropertyFormCell
, or for only some of the key properties.
<!-- SimplePropertyFormCell -->
<item name="onboarding_simple_property_focused_ref">
@style/Onboarding.SimplePropertyFormCell.Focused
</item>
<item name="onboarding_simple_property_focused_text_color">@color/sap_ui_formcell_key</item>
<item name="onboarding_simple_property_unfocused_ref">
@style/Onboarding.SimplePropertyFormCell.Unfocused
</item>
<item name="onboarding_simple_property_unfocused_text_color">@color/sap_ui_base_text</item>
The customization uses the same approach described above for the buttons. For example, in the client code:
<!-- SimplePropertyFormCell -->
<item name="onboarding_simple_property_focused_text_color">@color/colorAccent</item>
<item name="onboarding_simple_property_unfocused_text_color">@color/colorPrimaryDark</item>
Besides the theme attributes provided in FioriTheme.Onboarding
, to customize the active SimplePropertyFormCell
border, we need to define the following color:
<!-- colors.xml -->
<!-- SimplePropertyFormCell active value border -->
<color name="sap_ui_field_active_border_color">@color/colorPrimaryDark</color>
SimplePropertyFormCell
is one of the UI widgets in the Fiori component. For detailed information on customizing Fiori UI widgets, see Fiori document.
Other UI Elements¶
The onboarding screens are also comprised of additional UI elements. The complete style definitions and colors for these UI elements in the sample app are:
<!-- styles.xml -->
<style name="AppTheme" parent="FioriTheme.Onboarding">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!-- Sign In screen avatar background -->
<item name="onboarding_avatar_background">@color/colorPrimary</item>
<!-- If commented out, the default value in the 'onboarding' theme will be used.
<item name="onboarding_avatar_text_color">@color/onboarding_avatar_text_color</item>
-->
<!-- onboarding raised button -->
<item name="onboarding_button_raised_background_pressed">@color/colorPrimary</item>
<item name="onboarding_button_raised_background_disabled">@color/colorPrimaryDark</item>
<item name="onboarding_button_raised_background">@color/colorPrimary</item>
<!-- onboarding flat button -->
<item name="onboarding_button_flat_text">@color/colorAccent</item>
<item name="onboarding_button_flat_text_disabled">@color/colorPrimaryDark</item>
<item name="onboarding_button_flat_background">@color/onboarding_default_background</item>
<!-- SimplePropertyFormCell -->
<item name="onboarding_simple_property_focused_text_color">@color/colorAccent</item>
<item name="onboarding_simple_property_unfocused_text_color">@color/colorPrimaryDark</item>
<!-- Consent screen toolbar button -->
<item name="onboarding_consent_screen_toolbar_close_button_color">@color/colorPrimary</item>
<!-- Passcode rule checker -->
<item name="onboarding_passcode_rule_checker_pass_color">@color/colorAccent</item>
<item name="onboarding_passcode_rule_checker_not_pass_color">@color/colorPrimaryDark</item>
<!-- Top border only toolbar for the Passcode/EULA screens -->
<!-- Usually this color is similar to the background of the screen -->
<item name="onboarding_toolbar_divider_color">@color/onboarding_top_border_only_toolbar</item>
</style>
<!-- colors.xml -->
<!-- The background of the onboarding screens -->
<color name="onboarding_default_background">#F6F6F6</color>
<!-- The border color of the bottom action bar on the Passcode/EULA screens -->
<color name="onboarding_top_border_only_toolbar">@color/onboarding_avatar_text_color</color>
<!-- SimplePropertyFormCell active value border -->
<color name="sap_ui_field_active_border_color">@color/colorPrimaryDark</color>
If the application is using some Fiori components, it's highly recommended for the application's theme (usually AppTheme
by default) in AndroidManifest.xml
to extend Theme.Fiori.Horizon
. Otherwise, some Fiori attributes may need to be defined in the customized theme. FioriTheme.Onboarding
also extends Theme.Fiori.Horizon
.
Integrate with Flows¶
To successfully start FlowActivity
, the application's theme in AndroidManifest.xml
should extend a NoActionBar
theme or add the following two lines into the theme:
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
With the above style specified in the client code, the flows component must be notified about the customized theme. To do this, use the getApplicationTheme
flow option in FlowOptions
.
Note
The themes for application and activities in AndroidManifest.xml
are independent of those in FlowOptions
. That is to say, the themes for application and activities can be completely different from the theme in FlowOptions
. For example, the themes for application and activities in AndroidManifest.xml
can extend Theme.MaterialComponents.DayNight.NoActionBar
, which has nothing to do with Fiori, while the theme in FlowOptions
extends FioriTheme.Onboarding
.
val flowContext = FlowContext(
appConfig = AppConfig.Builder().applicationId("app_id").build(),
flowRequestCode = 100,
multipleUserMode = true,
flowStateListener = MyFlowStateListener(),
flowActionHandler = MyFlowActionHandler(),
flowOptions = FlowOptions(
appTheme = R.style.AppTheme
)
)
Flow.start(this@WelcomeActivity, flowContext) { requestCode, resultCode, _ ->
if (resultCode == Activity.RESULT_OK) {
startMainBusinessActivity()
}
}
FlowContext flowContext = new FlowContextBuilder()
.setApplication(appConfig)
.setMultipleUserMode(false)
.setFlowStateListener(new WizardFlowStateListener(
(SAPWizardApplication) context.getApplication()))
.setFlowOptions(new FlowOptions() {
@Override
public int getApplicationTheme() {
return R.style.AppTheme;
}
})
.build();
Flow.Companion.start(context, flowContext, (code, result, data) -> {
if(result == RESULT_OK) {
logger.debug("ok");
}
return null;
});
The application theme in FlowOptions
has to extend a "Fiori-based" theme and we strongly recommend extending FioriTheme.Onboarding
to make sure flows works properly. The onboarding screens in flows follow the Fiori design precisely, so a "Fiori-based" theme that covers the Fiori attributes used in flows is necessary.
You can also use the flows component as the framework to host your own flow. When you develop a flow step for the custom flow, with the getApplicationTheme()
method present, the custom flow step should also do the following:
class HelpFragment : FlowStepFragment() {
private lateinit var binding: Demov2FragmentHelpBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = Demov2FragmentHelpBinding.inflate(cloneLayoutInflater(inflater), container, false)
return binding.root
}
...
}
In the preceding code snippet, cloneLayoutInflater
is a function defined in FlowStepFragment
that can be used in child classes. Its purpose is to apply the client theme onto the custom flow step fragment.
Implementing Onboarding Screens Without Using Flows¶
If your mobile app does not use the flows component to handle the onboarding process, or if in one of your activities or fragments you want to use the onboarding screens and apply your own theme to them, you can implement one or more of the following scenarios.
Onboarding Screen in Activity¶
Your activity must define the theme in the AndroidManifest.xml
file:
<!-- AndroidManifest.xml -->
<activity
android:name=".WelcomeActivity"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- styles.xml -->
<style name="AppTheme.NoActionBar" parent="AppTheme">
...
</style>
Onboarding Screen in Fragment¶
Use the following code in the onCreateView
of the fragment.
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val themeWrapper = ContextThemeWrapper(
activity,
R.style.AppTheme
)
binding = Demov2FragmentHelpBinding.inflate(layoutInflater.cloneInContext(themeWrapper), container, false)
return binding.root
}
Onboarding Screen in Fullscreen Mode¶
In 'SAP Fiori' design, all onboarding screens are in fullscreen mode. In this mode, the status bar has the same background color as the rest of the screen. When using the flows component to handle the onboarding process, all the screens for the predefined flows are in fullscreen mode.
You can use the flows component as a framework to host your own custom flow. Use the isApplyFioriStyleForCustomFlow
flow option of FlowOptions
in your client code to fully control the presentation of the flow steps.
/**
* The predefined onboarding flows use the same Fiori design, fullscreen mode, which
* has a transparent Android status bar. If the custom flow also wants to use this Fiori
* design, change this to 'true'. By default it's false.
*/
open fun isApplyFioriStyleForCustomFlow() = fioriStyleForCustomFlow
By default, the option is 'false'. To set the screens in the custom flow to be full screen, turn this option on.
For additional information, see Enable fullscreen mode. To enable fullscreen mode in other parts of the mobile app, you need to modify the client code to handle it.