Props
Litho uses a unidirectional data flow with immutable inputs. Following the name established by React, the inputs that a Component
takes are known as props.
Defining and using Props
The props for a given Component
are the union of all arguments annotated with @Prop
in your spec methods. You can access the value of the props in all the methods that declare it as an @Prop
parameter.
The same prop can be defined and accessed in multiple lifecycle methods. The annotation processor will ensure you're using consistent prop types and consistent annotation parameters across all the spec methods.
Take the following Component
spec, for example:
MyComponentSpec
defines two props: a String prop called prop1
and an int prop named prop2
. prop1
is optional and it needs to be marked as such in all the methods that define it, otherwise the annotation processor will throw an exception.
When the lifecycle methods get called, the @Prop
parameters will hold the value passed down from the Component's parent when the Component was created (or their default values).
Props are defined and used the same way in LayoutSpecs
and MountSpecs
.
Setting Props
For each unique prop defined on the spec, the annotation processor creates a builder pattern method on the Component Builder that has the same name as the prop and that takes as only parameter the value to set for that prop.
You pass down values for these props by calling the appropriate methods on the generated Component Builder:
Prop defaults
PropDefault
can be used for setting
the default value of an optional Prop
in a LayoutSpec
or MountSpec
. The annotated field must
be a constant (i.e. static final
) with the same name and type as the Prop
. We'll often want to
define explicit default values for our optional props instead of simply using Java's defaults.
Let's see an how we can declare and use PropDefault
.
PropDefault
also support values from Resources via setting a resType
and resId
. Let's define
a PropDefault
with a resource value:
Resource Types
When creating layouts, it's very common to use values from Android's resource system such as dimensions, colors, strings, etc. Litho provides convenient ways to set prop values from Android resources using annotations.
Let's consider a simple example:
In the example above, MyComponent
has props that are expected to take a color integer (someColor
), a pixel dimension (someSize
), and a string (someString
) as value. Very often, you'll want to set the value of these props using resource values:
The framework allows you to annotate props with resource types so that your component builder has convenience methods to use resource values directly.
With the changes above, MyComponent
's builder will contain Res, Attr, Dip, and Px methods for the annotated props according to their resource types. So you'll be able to do the following:
Other supported resource types are ResType.STRING_ARRAY
, ResType.INT
, ResType.INT_ARRAY
, ResType.BOOL
, ResType.COLOR
, ResType.DIMEN_OFFSET
, ResType.FLOAT
, and ResType.DRAWABLE
.
Variable Arguments
Sometimes, you want to support having a list of items. This can unfortunately
be a bit painful since it requires the developer to make a list, add all the
items to it, and pass list to the component builder's method. The varArg
parameter aims to makes this a little easier.
This can then be used as follows:
This also works for props with a resType
. For instance, given a Component like this:
You can add multiple sizes through calls to the builder:
Immutability
The props of a Component are read-only. The Component's parent passes down values for the props when it creates the Component and they cannot change throughout the lifecycle of the Component. If the props values must be updated, the parent has to create a new Component and pass down new values for the props. The props objects should be made immutable. Due to background layout, props may be accessed on multiple threads. Props immutability ensures that no thread safety issues can happen during the component's lifecycle.
Common Props
Common props are props that are available on all Components, e.g. margin
, padding
, flex
etc. A full list of CommonProps can be found in the code here.
You may want to access a Common Prop inside your Component (e.g. to see if a click handler was set on it), in which case you should use set @Prop
param isCommonProp
, and name your prop using the same name as the Common Prop. If you wish to override the behavior of the Common Prop, then you should also set the @Prop
param overrideCommonPropBehavior
to true
.