9 Skinning MAF Applications
This chapter includes the following sections:
Introduction to MAF Application Skins
MAF uses cascading style sheet (CSS) language-based skins to make sure that all application components within a MAF application (including those used in its constituent application features) share a consistent look and feel.
Rather than change how a MAF application looks by re-configuring MAF AMX or HTML components, you can create, or extend, a skin that changes how components display.
Creating or editing a skin to change the look and feel of your MAF application is an iterative process. You can create a skin and deploy it to a device to view the result. You can continue this process until your skin renders the result that you want. The developer tools that the Android and iOS platforms provide to inspect and debug user interface code like CSS, HTML, and JavaScript are an invaluable resource for this task. For information about how you can use these tools with your MAF application, see How to Debug UI Code on the Android Platform and How to Debug UI Code on the iOS Platform. Use Visual Studio to debug user interface code in MAF applications that you deploy to the Universal Windows Platform. For information, see How to Debug UI Code on the Universal Windows Platform.
The following are the supported skin families and versions that MAF uses to define the selectors that determine the appearance of MAF AMX pages:
amx mobileAlta-1.0 mobileAlta-1.1 mobileAlta-1.2 mobileAlta-1.3 mobileAlta-1.4 mobileAlta-1.5 mobileAlta-1.6
By default, a new MAF application that you create uses the latest version of the mobileAlta
skin family. An application that you migrate from a previous release to the current release continues to use the skin that it was configured to use prior to migration. If you want the migrated application to use another skin (for example, the latest version of mobileAlta
), you need to edit the maf-config.xml
file, as described in Specifying a Skin for an Application to Use.
Figure demonstrates the difference in look and feel between the mobileAlta
skin family and another skin family by showing the same application screen rendering using the different skins. The mobileAlta
skin family renders on the left.
Figure 9-1 Comparison of Look and Feel Provided by mobileAlta and Another Skin
Description of "Figure 9-1 Comparison of Look and Feel Provided by mobileAlta and Another Skin"
You can view all the resources (CSS files and images) that the skin for your MAF application uses by deploying your MAF application to a device, emulator or simulator. Deployment moves these resources to a www\css
directory that it creates within the platform-specific artifacts that the deployment process generates. For iOS deployments, the www\css
directory is located within the temporary_xcode_project
directory. The iOS deployment packages these resources into an Oracle_ADFmc_Container_Template.zip
file that is added to the created .IPA
file. For Android deployments, the directory path is %app%\deploy\Android1\framework\build\java_res\assets\www\css
where Android1
is the name of the deployment profile. Android deployment packages these resources into an assets.zip
file that is added to the created .APK
file. Note that JDeveloper’s Build > Clean All command removes the deploy
directory and its sub-directories, including the www\css
directory.
Caution:
Do not write styles that rely on the MAF DOM structures. Furthermore, some of the selectors defined in these files may not be supported.
You use the maf-config.xml
file, described in About the maf-config.xml File, and the maf-skins.xml
file, described in About the maf-skins.xml File, to control the skinning of the MAF application. The maf-config.xml
file designates the default skin family used to render application components and the maf-skins.xml
file enables you to customize the default skin family or to define a new skin family.
About the maf-config.xml File
After you create a MAF application, JDeveloper populates the maf-config.xml
file to the MAF application's META-INF node. The file itself is populated with the base MAF skin family, mobileAlta
, illustrated in the following example.
<?xml version="1.0" encoding="UTF-8" ?> <adfmf-config xmlns="http://xmlns.oracle.com/adf/mf/config"> <skin-family>mobileAlta</skin-family> <skin-version>v1.5</skin-version> .... </adfmf-config>
Note:
You can determine the skin value at runtime using EL expressions. See Enabling End Users Change an Application's Skin at Runtime.
If you do not specify values for the <skin-family>
or <skin-version>
tags, the MAF application automatically uses the latest skin family or skin version.
MAF applies skins as a hierarchy, with device-specific skins being applied first, followed by platform-specific skins, and then the base skin, mobileAlta
. In terms of MAF's mobileAlta
skin family, this hierarchy is expressed as follows:
-
mobileAlta.
<DeviceModel>
(for example,mobileAlta.iPhone5,3
) -
mobileAlta.iOS
ormobileAlta.Android
-
mobileAlta
Tip:
Deploy the DeviceDemo sample application to the device or platform you want to retrieve the values for if you plan to create a device-specific or platform-specific skin. The Properties application feature in the DeviceDemo sample application displays the values for the device model and platform the application runs on. See MAF Sample Applications.Figure provides a visual illustration of how MAF applies this hierarchy of skins at runtime. Note also that the SkinningDemo
sample application, described in MAF Sample Applications, demonstrates this implementation.
MAF gives precedence to selectors defined at the device-specific level of this hierarchy. In other words, MAF overwrites a selector defined in mobileAlta.iOS
with the mobileAlta.iPhone5,3
definition for the same selector. The <extends>
element, described in About the maf-skins.xml File, defines this hierarchy for the MAF runtime. For information on how skins are applied at various levels, see What You May Need to Know About Skinning.
Figure 9-2 MAF Skin Hierarchy Application at Runtime
Description of "Figure 9-2 MAF Skin Hierarchy Application at Runtime"
About the maf-skins.xml File
The maf-skins.xml
file located in the META-INF node of the application controller project allows you to either define a new skin by extending an existing skin, or, add a new style sheet to an existing skin.
By default, this file is empty, but the elements listed in Table 9-1 describe the child elements that you can use to populate this file to extend mobileAlta
or to define the CSS files that are available to the application. You use the <skin>
element to create new skins or to extend an existing skin.
Table 9-1 Child Elements of the <skin> Element
Elements | Description |
---|---|
|
A required element that identifies the skin in the
For example, specify |
|
A required element that identifies the skin family. |
|
Use this element to extend an existing skin by specifying the skin id of the skin you want to extend. <skin> <id>mySkin-v1</id> <family>mySkin</family> <extends>mobileAlta-v1.6</extends> <style-sheet-name>styles/myskin.css</style-sheet-name> <version> <name>v1</name> </version> </skin> |
|
Use a relative URL to specify the location of the CSS file within your MAF application's project. For example, the
|
|
Specify different versions of a skin. See Versioning MAF Skins. |
Table 9-2 lists elements that you can use to define the <skin-addition>
element in a MAF CSS when you integrate a style sheet into an existing skin.
Table 9-2 The <skin-addition> Child Elements
Element | Description |
---|---|
|
Specify the ID of the skin that you need to add an additional style sheet to. Possible values include the skins provided by MAF (for example, |
|
Use a relative URL to specify the location of the CSS file within your MAF application's project. For example, the
|
The following example illustrates designating the location of the CSS file in the <style-sheet-name>
element and the target skin family in <skin-id>
.
<?xml version="1.0" encoding="UTF-8" ?> <adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/config"> <skin-addition> <skin-id>mobileAlta-v1.6.iOS</skin-id> <style-sheet-name>skins/mystyles.iphone.addition1.css</style-sheet-name> </skin-addition> </adfmf-skins>
You can use the <skin-id>
and <style-sheet-name>
elements to render to a particular iOS or Android device, or alternatively, you can define these elements to handle the styling for all of the devices of a platform. Table 9-3 provides examples of using these elements to target all of the devices belonging to the iOS platform, as well as specific iOS device types (tablets, phones, and simulators).
Tip:
Consider using the DeviceDemo sample application, described in MAF Sample Applications, to retrieve information about the device model.
Table 9-3 Platform- and Device-Specific Styling
Device | Example |
---|---|
iPhone |
<skin-addition> <skin-id>mobileAlta-v1.6.iPhone5,1</skin-id> <style-sheet-name>iPhoneStylesheet.css</style-sheet-name> </skin-addition> |
iPad |
<skin-addition> <skin-id>mobileAlta-v1.6.iPad4,2</skin-id> <style-sheet-name>iPadStylesheet.css</style-sheet-name> </skin-addition> |
iPhone Simulator |
<skin-addition> <skin-id>mobileAlta-v1.6.iPhone Simulator x86_64</skin-id> <style-sheet-name>iPhoneSimStylesheet.css</style-sheet-name> </skin-addition> |
All iOS Devices |
<skin-addition> <skin-id>mobileAlta-v1.6.iOS</skin-id> <style-sheet-name>iOSSimStylesheet.css</style-sheet-name> </skin-addition> |
Adding a Custom Skin to an Application
To add a custom skin to your application, create a CSS file within JDeveloper, which places the CSS in a project's source file for deployment with the application.
To add a custom skin to an application:
- In the Applications window, right-click the ApplicationController project and choose New > CSS File.
- In the Create Cascading Style Sheet dialog, specify a name and directory for the CSS file.
- Click OK.
You can now open the CSS in the CSS editor and define styles for your application.
Specifying a Skin for an Application to Use
You configure values in the maf-config.xml
file that determine what skin the application uses.
To specify a skin for an application to use:
Example 9-1 Configuration to Specify a Skin for an Application
<adfmf-config xmlns="http://xmlns.oracle.com/adf/mf/config"> <skin-family>mobileAlta</skin-family> <skin-version>v1.6</skin-version> </adfmf-config>
Note:
Set an EL expression as the value for the <skin-family>
element if you want to dynamically select the skin the application uses at runtime. See Enabling End Users Change an Application's Skin at Runtime.
Registering a Custom Skin
You register a custom skin by adding the property values to the maf-skins.xml
file that identify the custom skin to your application.
To register a custom skin:
Versioning MAF Skins
You can version your MAF skins if you want to distinguish between skins.
You can specify version numbers for your skins in the maf-skins.xml
file using the <version>
element. Use this optional capability if you want to distinguish between skins that have the same value for the <family>
element in the maf-skins.xml
file. This capability is useful in scenarios where you want to create a new version of an existing skin in order to change some existing behavior. Note that when you configure an application to use a particular skin, you do so by specifying values in the maf-config.xml
file, see Specifying a Skin for an Application to Use.
You specify a version for your skin by entering a value for the <version>
element in the maf-skins.xml
file.
Best Practice:
Specify version information for each skin that you register in the application's maf-skins.xml
file.
To version a MAF skin:
- In the Applications window, double-click the
maf-skins.xml
file. By default, this is in the META-INF node of the application controller project. - In the Structure window, right-click the skin node for the skin that you want to version and choose Insert inside skin > version.
- In the Insert version dialog, select true from the default list if you want your application to use this version of the skin when no value is specified in the
<skin-version>
element of themaf-config.xml
file, see Specifying a Skin for an Application to Use. - Enter a value in the name field. For example, enter
v1
if this is the first version of the skin. - Click OK.
What Happens When You Version Skins
The version information that you configure for skins takes precedence over platform and device values when an application applies a skin at runtime.
At runtime, a MAF application applies a device-specific skin before it applies a platform-specific skin. If skin version information is specified, the application first searches for a skin that matches the specified skin version value. If the application finds a skin that matches the skin version and device values, it applies this skin. If the application cannot find a skin with the specified skin version in the device-specific skins, it searches for a skin with the specified version in the platform-specific skins. If it does not find a skin that matches the specified version in the available platform-specific skins, it searches the base skins.
Example 9-2 shows an example maf-skins.xml
that references three skins (customFamily-v1.iphone5,3
, customFamily-v2.iPhone5,3
and customFamily-v3.iPhone5,3
). Each of these skins have the same value for the <family>
element (customFamily
). The values for the child elements of the <version>
elements distinguish between each of these skins.
At runtime, an application that specifies customFamily
as the value for the <skin-family>
element in the application's maf-config.xml
file uses customFamily-v1.iphone5,3
because this skin is configured as the default skin in the maf-skins.xml
file. You can override this behavior by specifying a value for the <skin-version>
element in the maf-config.xml
file, as described in Specifying a Skin for an Application to Use. For example, if you specify v2
as a value for the <skin-version>
element in the maf-config.xml
file, the application uses customFamily-v2.iPhone5,3
instead of customFamily-v1.iphone5,3
that is defined as the default in the maf-skins.xml
file.
If you do not specify the skin version to pick (using the <skin-version>
element in the maf-config.xml
file), then the application uses the skin that is defined as the default using the <default>true</default>
element in the maf-skins.xml
file. If you do not specify a default skin, the application uses the last skin defined in the maf-skins.xml
file. In Example 9-2, the last skin to be defined is customFamily-v3.iPhone5,3
.
Example 9-2 maf-skins.xml File with Versioned Skin Files
<?xml version="1.0" encoding="UTF-8" ?> <adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/skin"> <skin id="s1"> <family>customFamily</family> <id>customFamily-v1.iphone5,3</id> <extends>customFamily-v1.iOS</extends> <style-sheet-name>iphone.css</style-sheet-name> <version> <default>true</default> <name>v1</name> </version> </skin> <skin id="s2"> <family>customFamily</family> <id>customFamily-v2.iPhone5,3</id> <extends>customFamily-v1.iOS</extends> <style-sheet-name>iphone-v2.css</style-sheet-name> <version> <name>v2</name> </version> </skin> <skin id="s3"> <family>customFamily</family> <id>customFamily-v3.iPhone5,3</id> <extends>customFamily-v1.iOS</extends> <style-sheet-name>iphone-v3.css</style-sheet-name> <version> <name>v3</name> </version> </skin> </adfmf-skins>
Overriding the Default Skin Styles
For a MAF AMX application, you can designate a specific style for the application feature implemented as MAF AMX, thereby overriding the default skin styles set at the application-level within the maf-config.xml
and maf-skins.xml
files.
You add individual styles to the application feature using a CSS file as the Includes file.
The Includes table in the overview editor for the maf-feature.xml
file enables you to add a CSS to a MAF AMX application feature.
Before you begin:
Create a MAF task flow as described in Creating Task Flows. Create or add a CSS file for the skin. You can create the CSS file by selecting the view controller project and then choosing New > CSS File. Alternatively, you can package the CSS file in a JAR file as follows:
-
From the main menu, choose Application > Project Properties.
-
In the Project Properties dialog, select the Libraries and Classpath page and click Add JAR/Directory.
-
In the Add Archive or Directory dialog, navigate to the JAR file that contains the skin you want to import and click Select.
The JAR file appears in the Classpath Entries list.
-
Click OK.
How to add a style sheet to an application feature:
-
Click Add to create a new row in the Includes table.
-
In the Insert Include dialog, complete the following fields:
-
File: Browse to select the CSS style sheet to add.
-
Type: Select StyleSheet from the dropdown list.
-
-
Click OK.
Note:
The
.CSS
file for the style sheet that you select must reside within the view controller project.
What You May Need to Know About Skinning
You can customize styles that can be applied when the application is deployed to different devices.
The CSS files defined in the maf-skins.xml
file, illustrated in Example 9-3, show how to extend a skin to accommodate the different display requirements of the Apple iPhone and iPad. These styles are applied in a descending fashion. The SkinningDemo sample application provides a demonstration of how customized styles can be applied when the application is deployed to different devices. This sample application is in the PublicSamples.zip
file at the following location within the JDeveloper installation directory of your development computer:
jdev_install/jdeveloper/jdev/extensions/oracle.maf/Samples
For example, at the iOS level, the stylesheet (mobileAlta
in Example 9-3) is applied to both an iPhone or an iPad. For device-specific styling, define the <skin-id>
elements for the iPhone and iPad skins. The skinning demo application illustrates the use of custom skins defined through this element.
Example 9-3 Skinning Levels Defined in the maf-skins.xml File
<?xml version="1.0" encoding="UTF-8" ?> <adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/skins"> <skin> <id>mobileAlta-v1.6.iPhone5,3</id> <family>mobileAlta</family> <extends>mobileAlta-v1.6.iOS</extends> <style-sheet-name>skins/mobileAlta-v1.6.iphone.css</style-sheet-name> </skin> <skin> <id>mobileAlta-v1.6.iPad iPad4,1</id> <family>mobileAlta</family> <extends>mobileAlta-v1.6.iOS</extends> <style-sheet-name>skins/mobileAlta-v1.6.ipad.css</style-sheet-name> </skin> <!-- Skin Additions --> <skin-addition> <skin-id>mobileAlta-v1.6.iPhone5,3</skin-id> <style-sheet-name>skins/mystyles.iphone.addition1.css</style-sheet-name> </skin-addition> <skin-addition> <skin-id>mobileAlta-v1.6.iPhone5,3</skin-id> <style-sheet-name>skins/mystyles.iphone.addition2.css</style-sheet-name> </skin-addition> <skin-addition> <skin-id>mobileAlta-v1.6.iOS</skin-id> <style-sheet-name>skins/mystyles.ios.addition2.css</style-sheet-name> </skin-addition> </adfmf-skins>
Adding a New Style Sheet to a Skin
You can add a CSS file to an existing skin instead of extending a skin.
To add a new style sheet to a skin
Caution:
Creating custom styles that use DOM-altering structures can cause MAF applications to hang. Specifically, the display
property causes rendering problems in the HTML that is converted from MAF AMX. This property, which uses such values as table
, table-row
, and table-cell
to convert components into a table, may result in table-related structures that are not contained within the appropriate parent table objects. Although this problem may not be visible within the application user interface itself, the logging console reports it through a Signal 10 exception.
Enabling End Users Change an Application's Skin at Runtime
You can configure your application to enable end users select an alternative skin at runtime.
You might configure this functionality when you want end users to render the application using a skin that is more suitable for their needs.
Figure shows how you might implement this functionality by displaying buttons to allow end users to change the skin the application uses at runtime. Configure the buttons on the page to set a scope value that can later be evaluated by the skin-family
property in the application's maf-config.xml
file.
Figure 9-5 Changing an Application's Skin at Runtime (on iOS)
Description of "Figure 9-5 Changing an Application's Skin at Runtime (on iOS)"
You enable end users change an application's skin by exposing a component that allows them to update the value of the skin-family
property in the application's maf-config.xml
file.
To enable end users change an application's skin at runtime:
Example 9-4 Managed Bean to Change an Application's Skin
package application; import javax.el.ValueExpression; import oracle.adfmf.amx.event.ActionEvent; import oracle.adfmf.framework.FeatureInformation; import oracle.adfmf.framework.api.AdfmfContainerUtilities; import oracle.adfmf.framework.api.AdfmfJavaUtilities; import oracle.adfmf.java.beans.PropertyChangeListener; import oracle.adfmf.java.beans.PropertyChangeSupport; public class SkinBean { private String skinFamily = "mobileAlta"; private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); public void setSkinFamily(String skinFamily) { String oldSkinFamily = this.skinFamily; this.skinFamily = skinFamily; propertyChangeSupport.firePropertyChange("skinFamily", oldSkinFamily, skinFamily); } public String getSkinFamily() { return skinFamily; } public void addPropertyChangeListener(PropertyChangeListener l) { propertyChangeSupport.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { propertyChangeSupport.removePropertyChangeListener(l); } public void switchToMobileAlta(ActionEvent ev){ this.switchSkinFamily("mobileAlta"); } public void switchToMobileFusionFx(ActionEvent ev) { this.switchSkinFamily("mobileFusionFx"); } public void switchSkinFamily(String family) { this.setSkinFamily(family); // reset all the features individually as follows to load the new skin FeatureInformation[] features = AdfmfContainerUtilities.getFeatures(); for (int i = 0; i < features.length; i++) { AdfmfContainerUtilities.resetFeature(features[i].getId()); } } }
What Happens at Runtime: How End Users Change an Application's Skin
At runtime, the end user uses the component that you exposed to select another skin.
This component submits the value that the end user selected to a managed bean that, in turn, sets the value of a managed bean property (skinFamily
). At runtime, the <skin-family>
property in the maf-config.xml
file reads the value from the managed bean using an EL expression. The managed bean in Example 9-4 also reloads the features in the application to use the newly-specified skin.
Tip:
Similar to the <skin-family>
property, you can use an EL expression to set the value of the <skin-version>
property in the maf-config.xml
file at runtime.