MAF controls inherit the standard behavior from the native controls. MAF modifies only the appearance of the controls. The MAF skinning mechanism uses a simple text-based configuration that lets you rebrand or reskin applications without requiring source code modifications.
You can easily define the configuration without extensive technical knowledge. Style configurations are simple XML files where you can specify properties for the MAF UI controls. The styling XML also includes inheritance logic which lets you reuse and extend existing components.
All MAF controls come with a default SAP style that is defined in a styling XML file, which you can find in the MAFUIComponents-Res Android library. The default SAP style satisfies the SAP product standards for the look of the UI elements. There is also a hard-coded default skin for all the controls.
To use the MAF skinning feature, configure the appearance of the UI elements in the styling XML and load the file when you launch the application. To use the runtime skinnability capabilities of MAF, you must publish the styling XML file on a remote server. The mobile application must implement logic that calls style-loading code each time it downloads a new version of the configuration bundle.
The style configuration defines the look of simple MAF controls. Each simple MAF UI control has a matching TargetType in the configuration file. Any properties you set for a TargetType are valid for all the UI elements of that type.
For example, the Button TargetType represents the android.widget.Button UI control.
Skinning based on control type is often too generic, so the style configuration also uses keys to define unique skins for each instance of a TargetType.
import com.sap.maf.uicontrols.MAFSkinManager; … MAFSkinManager.getInstance(this).loadStyle("customSkin", getResources().openRawResource(R.raw.styles_green)); try { MAFSkinManager.getInstance(this).setActiveStyle(”customSkin”); } catch (IllegalArgumentException e) {}To load the default SAP style, use:
MAFSkinManager sMan = MAFSkinManager.getInstance(activity); sMan.setDefaultStyle();
Configuration files are loaded incrementally. This means that if you load a new configuration file, it changes the appearance of only the controls that are redefined in the file, and updates only the properties that are explicitly described in the file. This way, you need not copy the entire SAPDefaultStyle.xml to change the appearance of a few controls. Create a new XML file and include only the styles you want to override.
<Style TargetType="Label" Key="DefLabel" platform="android"> <Setter Property="Foreground" Value="#ff333333" /> <!-- text color --> <Setter Property="FontFamily" Value="sans_serif" /> <!-- font size --> <Setter Property="FontSize" Value="18" /> <!-- font style --> </Style> <Style TargetType="Label" Key="LargeLabel" BasedOn="DefLabel" platform="android"> <Setter Property="FontSize" Value="22" /> <Setter Property="Foreground" Value="#ff003333" /> </Style>The first <Style> element defines the skinning properties for the Label target type, using the Key attribute so the substyle can refer to it. The second <Style> element is also defined for the Label target type, but inherits its values from the root style—defined in the BasedOn attribute, where the first style Key attribute value is used. The second <Style> element overwrites the FontSize and the ForeGround properties. Thus it becoms a large label flavor.
The Key attribute of the sub-style is called a flavor. Every UI component has a constructor in which you can define a flavor. Alternatively, you can define the flavor attribute in the layout XML, and when that component is inflated, the MAF skinning engine applies the skinning properties according to the flavor definition.
… MAFTextView lLabel = new MAFTextView(this, "LargeLabel"); …
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:x="http://schemas.sap.com/maf/2011/ux" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffffff" android:orientation="vertical" > <com.sap.maf.uicontrols.view.MAFTextView android:id="@+id/phone_numbers_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_height="wrap_content" x:flavor= "LargeLabel" /> </LinearLayout
Visual states are implemented by native controls. MAF cannot add new visual states; it can style only those states that are already supported. Visual states are declared in the styling XML file:
<Style TargetType="Button" Key="DefButton" platform="android"> <VisualStates> <VisualState Name="Unfocused_Enabled"> <Setter Property="Background" Value="#FFDDDDDD" /> <!-- background color --> <Setter Property="Foreground" Value="#FF333333" /> <!-- text color --> <Setter Property="Bg_Bottom_Shadow" Value="#80DDDDDD" /> <!-- background bottom shadow color --> <Setter Property="Bg_Dark_Bottom_Shadow" Value="#FF999999" /> <!-- background bottom dark shadow color --> <Setter Property="Bg_Top_Shadow" Value="#FFEBEBEB" /> <!-- background top shadow color --> </VisualState> <VisualState Name="Unfocused_Disabled"> <Setter Property="Background" Value="#80DDDDDD" /> <!-- background color --> <Setter Property="Foreground" Value="#33333333" /> <!-- text color --> <Setter Property="Bg_Bottom_Shadow" Value="#25DDDDDD" /> <!-- background bottom shadow color --> <Setter Property="Bg_Dark_Bottom_Shadow" Value="#80999999" /> <!-- background bottom dark shadow color --> <Setter Property="Bg_Top_Shadow" Value="#80EBEBEB" /> <!-- background top shadow color --> </VisualState> …… </Style>
The styling XML file uses the VisualState XML tag to declare a group of properties that belong to a specific visual state. The states are identified by the Name property of the VisualState XML tag. A style XML entry can have many VisualState tags, but they must all be declared inside the VisualStates XML tag. When you provide visual states, the MAF skinning engine checks the state of the control and selects the matching visual state style from the style of the control.