public class RhythmOverlayInflater
extends java.lang.Object
A default inflater that creates RhythmOverlays from text configuration using registered layer factories. Supports inflating multiple overlays from configuration files (see the docs) separated by newlines as well as separate overlays; supports comments and variables, and supporting custom spec layers by allowing to register spec layer factories.
The provided implementation is a reference one — developers are welcome to subclass this inflater or any classes of the inflation pipeline to override certain aspects, or implement their own inflation mechanisms (e.g. different lexers, parse-time validation, transformations, XML/JSON/YAML support etc) entirely from scratch should they need something different.
Modifier and Type | Class and Description |
---|---|
static class |
RhythmOverlayInflater.LayerConfig
A spec layer descriptor holding arguments and metadata, used internally by
RhythmOverlayInflater to carry
values needed to inflate individual layers and their hierarchies. |
Modifier and Type | Field and Description |
---|---|
protected boolean |
mAreMagicVariablesEnabled |
protected android.content.Context |
mContext |
protected android.util.DisplayMetrics |
mDisplayMetrics |
protected java.util.Map<java.lang.String,RhythmSpecLayerFactory> |
mFactories |
protected static java.util.regex.Pattern |
PATTERN_ARGUMENTS
A regex to search for arguments in configuration string by a following template: key[=value]
|
protected static java.util.regex.Pattern |
PATTERN_VARIABLES
A regex to validate and parse variables in configuration string by a following template: @variable=value
|
Constructor and Description |
---|
RhythmOverlayInflater(android.content.Context context)
Create a new instance of overlay inflater with no factories registered.
|
Modifier and Type | Method and Description |
---|---|
RhythmOverlayInflater |
addAlias(java.lang.String existingLayerType,
java.lang.String aliasLayerType)
Add an alias for arbitrary layer type.
|
static RhythmOverlayInflater |
createDefault(android.content.Context context)
Create a new instance of default overlay inflater.
|
java.util.List<RhythmOverlay> |
inflate(int rawResId)
Inflate a Rhythm configuration file into a list of
RhythmOverlays , which you can then
assign to a group, or make sub-lists of and assign to different groups. |
java.util.List<RhythmOverlay> |
inflate(java.util.List<java.lang.String> configStrings)
Same as
inflate(int) , but accepts the configuration file already split in lines as strings. |
java.util.List<RhythmOverlay> |
inflate(java.lang.String configString)
Same as
inflate(int) , but accepts a string for the whole overlay configuration file. |
RhythmSpecLayer |
inflateLayer(java.lang.String configString,
java.util.Map<java.lang.String,java.lang.String> vars)
Inflate an individual layer from raw configuration string and optional variables
|
protected RhythmSpecLayer |
inflateLayerInternal(RhythmOverlayInflater.LayerConfig config,
int lineNumber)
Inflate an individual layer from already parsed layer configuration.
|
RhythmOverlay |
inflateOverlay(java.util.List<java.lang.String> configStrings)
Inflate a single overlay from overlay configuration already presented as separate lines.
|
RhythmOverlay |
inflateOverlay(java.util.List<java.lang.String> configStrings,
java.util.Map<java.lang.String,java.lang.String> vars)
Inflate a single overlay from overlay configuration already presented as separate lines.
|
RhythmOverlay |
inflateOverlay(java.lang.String configString)
Inflate a single overlay from overlay configuration string according to the syntax spec.
|
RhythmOverlay |
inflateOverlay(java.lang.String configString,
java.util.Map<java.lang.String,java.lang.String> vars)
Inflate a single overlay from overlay configuration string according to the syntax spec.
|
protected RhythmOverlay |
inflateOverlayInternal(java.util.List<java.lang.String> configStrings,
java.util.Map<java.lang.String,java.lang.String> globalVars,
int offset)
Internal method for inflating an overlay from separate config lines, with provided global variables map, and
possibly as a part of an overlay config file.
|
static boolean |
isEmptyOrComment(java.lang.String line)
Utility method that determines whether the line is empty or a comment one (starts with
// ) and thus
should be ignored. |
protected RhythmOverlayInflater.LayerConfig |
parseConfigInternal(java.lang.String configString,
java.util.Map<java.lang.String,java.lang.String> vars,
int lineNumber)
Parses a line with single layer configuration.
|
RhythmOverlayInflater |
registerFactory(java.lang.String layerType,
RhythmSpecLayerFactory factory)
Register a factory for provided layer type.
|
protected java.lang.String |
resolveVariableInternal(java.util.Map<java.lang.String,java.lang.String> vars,
java.lang.String value,
int lineNumber)
Resolve variable value: if it's a reference to another variable (i.e.
|
RhythmOverlayInflater |
setMagicVariablesEnabled(boolean enabled)
Enable or disable “magic variables” support in this inflater instance.
|
protected static final java.util.regex.Pattern PATTERN_ARGUMENTS
protected static final java.util.regex.Pattern PATTERN_VARIABLES
protected android.content.Context mContext
protected android.util.DisplayMetrics mDisplayMetrics
protected java.util.Map<java.lang.String,RhythmSpecLayerFactory> mFactories
protected boolean mAreMagicVariablesEnabled
public RhythmOverlayInflater(android.content.Context context)
registerFactory(String, RhythmSpecLayerFactory)
). If you need an inflater with all bundled spec layers
pre-configured, use createDefault(Context)
instead.context
- ContextcreateDefault(Context)
public static RhythmOverlayInflater createDefault(android.content.Context context)
Create a new instance of default overlay inflater. It comes pre-configured to inflate all bundled RhythmSpecLayer
types, and you can add custom factories for your custom spec layers.
By default, GridLines
, Keyline
, RatioKeyline
, and Fill
layer instances are cached and reused for the
same configuration lines — if you don't want this behavior (e.g. if you want to mutate the inflated layers
individually afterwards), create an empty inflater and register the factories yourself like this:
RhythmOverlayInflater inflater = new RhythmOverlayInflater(context);
inflater.registerFactory(GridLines.Factory.LAYER_TYPE, new GridLines.Factory());
inflater.registerFactory(Keyline.Factory.LAYER_TYPE, new Keyline.Factory());
inflater.registerFactory(RatioKeyline.Factory.LAYER_TYPE, new RatioKeyline.Factory());
inflater.registerFactory(Fill.Factory.LAYER_TYPE, new Fill.Factory());
inflater.registerFactory(Inset.Factory.LAYER_TYPE, new Inset.Factory());
inflater.registerFactory(Columns.Factory.LAYER_TYPE, new Columns.Factory());
inflater.registerFactory(DimensionsLabel.Factory.LAYER_TYPE, new DimensionsLabel.Factory());
context
- ContextRhythmOverlayInflater(Context)
public RhythmOverlayInflater setMagicVariablesEnabled(boolean enabled)
Enable or disable “magic variables” support in this inflater instance. Enabling this will allow to
specify default arguments for spec layers by defining global and local variables named with the following
pattern: @{layer_name}_{arg_name}
, where dashes are replaced with underscores.
Warning:“magic variables” is an experimental feature and therefore disabled by default. Normally it shouldn't have significant impact on performance, yet it's advised to only enable it if using magic variables is really desirable over explicitly setting values to spec layers individually.
enabled
- true to enable magic variables support, false to disable it.public RhythmOverlayInflater registerFactory(@NonNull java.lang.String layerType, @NonNull RhythmSpecLayerFactory factory)
layerType
- string that identifies a specific spec layer class; the first argument in each config linefactory
- a factory object that will inflate config line into a layerpublic RhythmOverlayInflater addAlias(@NonNull java.lang.String existingLayerType, @NonNull java.lang.String aliasLayerType)
registerFactory(String,
RhythmSpecLayerFactory)
multiple times with different strings and the same factory objects to avoid lookups.existingLayerType
- layer type string for layer to alias (used for lookup)aliasLayerType
- layer type string to map to the same factorypublic java.util.List<RhythmOverlay> inflate(@RawRes int rawResId)
RhythmOverlays
, which you can then
assign to a group, or make sub-lists of and assign to different groups.rawResId
- Raw configuration file with syntax according to the docsinflate(List)
public java.util.List<RhythmOverlay> inflate(java.lang.String configString)
inflate(int)
, but accepts a string for the whole overlay configuration file. This method may
come in handy if you need to bulk inflate several overlays from strings known at runtime.configString
- Configuration file passed in whole as a string. Must follow the same syntax rules as the
configuration file, e.g. overlays must be separated by an empty lineinflate(int)
,
inflate(List)
public java.util.List<RhythmOverlay> inflate(java.util.List<java.lang.String> configStrings)
Same as inflate(int)
, but accepts the configuration file already split in lines as strings.
This method walks over the lines and determines how the config should be split into separate overlays.
configStrings
- Configuration file split as separate lines. Must follow the same syntax rules as the
configuration file, that is, no null
strings, and overlays being separated by
an empty lineinflate(int)
,
inflate(String)
public RhythmOverlay inflateOverlay(java.lang.String configString)
configString
- layer configuration string, following the syntax rulespublic RhythmOverlay inflateOverlay(java.lang.String configString, @NonNull java.util.Map<java.lang.String,java.lang.String> vars)
configString
- layer configuration string, following the syntax rulesvars
- the @key->value map of the values that can be referenced within this overlay (see the
docs)public RhythmOverlay inflateOverlay(java.util.List<java.lang.String> configStrings)
configStrings
- layer configuration split in linespublic RhythmOverlay inflateOverlay(java.util.List<java.lang.String> configStrings, @NonNull java.util.Map<java.lang.String,java.lang.String> vars)
configStrings
- layer configuration split in linesvars
- the @key->value map of the values that can be referenced within this overlay (see the
docs)protected RhythmOverlay inflateOverlayInternal(java.util.List<java.lang.String> configStrings, @NonNull java.util.Map<java.lang.String,java.lang.String> globalVars, int offset)
configStrings
- layer configuration split in linesglobalVars
- map of global variablesoffset
- index of the line where this overlay starts in the context of an outer config. Pass 0 if
inflating this overlay on its ownpublic RhythmSpecLayer inflateLayer(java.lang.String configString, @NonNull java.util.Map<java.lang.String,java.lang.String> vars)
configString
- configuration string to parse and feed to layer's factoryvars
- map of @key->value mappings used to resolve argument references (e.g.
@primary=#FF0000
to use in color=@primary
). Cannot be
null
— pass Collections.EMPTY_MAP
if there are no variables.protected RhythmSpecLayer inflateLayerInternal(RhythmOverlayInflater.LayerConfig config, int lineNumber)
config
- parsed layer configurationlineNumber
- number of the configuration line we're inflating. Required for error reporting.protected RhythmOverlayInflater.LayerConfig parseConfigInternal(java.lang.String configString, @NonNull java.util.Map<java.lang.String,java.lang.String> vars, int lineNumber)
RhythmOverlayInflater.LayerConfig
or enclosed ArgumentsBundle
.configString
- configuration string, indented with spaces if required, starting with layer title and
containing args or key=value pairsvars
- map of @key->value mappings used to resolve argument references (e.g.
@primary=#FF0000
to use in color=@primary
)lineNumber
- Line number to report in case of errorprotected java.lang.String resolveVariableInternal(@NonNull java.util.Map<java.lang.String,java.lang.String> vars, java.lang.String value, int lineNumber)
vars
- Variables map, as resolved at the momentvalue
- Value that's either a reference to resolve or a concrete valuelineNumber
- Line number to report in case of errorpublic static boolean isEmptyOrComment(java.lang.String line)
//
) and thus
should be ignored.line
- line to test, should be pre-trimmed