There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like
TextInput, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, it's quite easy to wrap up these existing components for seamless integration with your React Native application.
Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with Android SDK programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing
ImageViewcomponent available in the core React Native library.
Native views are created and manipulated by extending
ViewManager or more commonly
SimpleViewManager . A
SimpleViewManager is convenient in this case because it applies common properties such as background color, opacity, and Flexbox layout.
These subclasses are essentially singletons - only one instance of each is created by the bridge. They vend native views to the
NativeViewHierarchyManager, which delegates back to them to set and update the properties of the views as necessary. The
Vending a view is simple:
createViewManagersof the applications package.
In this example we create view manager class
ReactImageManager that extends
SimpleViewManager of type
ReactImageView is the type of object managed by the manager, this will be the custom native view. Name returned by
Views are created in the
createViewInstance method, the view should initialize itself in its default state, any properties will be set via a follow up call to
@ReactPropGroup) annotation #
@ReactPropGroup). Setter method should take view to be updated (of the current view type) as a first argument and property value as a second argument. Setter should be declared as a
void method and should be
public. Property type sent to JS is determined automatically based on the type of value argument of the setter. The following type of values are currently supported:
@ReactProp has one obligatory argument
name of type
String. Name assigned to the
@ReactProp annotation linked to the setter method is used to reference the property on JS side.
@ReactProp annotation may take following optional arguments:
defaultFloat. Those arguments should be of the corresponding primitive type (accordingly
float) and the value provided will be passed to the setter method in case when the property that the setter is referencing has been removed from the component. Note that "default" values are only provided for primitive types, in case when setter is of some complex type,
null will be provided as a default value in case when corresponding property gets removed.
Setter declaration requirements for methods annotated with
@ReactPropGroup are different than for
@ReactProp, please refer to the
@ReactPropGroup annotation class docs for more information about it.
IMPORTANT! in ReactJS updating the property value will result in setter method call. Note that one of the ways we can update component is by removing properties that have been set before. In that case setter method will be called as well to notify view manager that property has changed. In that case "default" value will be provided (for primitive types "default" can value can be specified using
defaultFloat, etc. arguments of
@ReactProp annotation, for complex types setter will be called with value set to
The final Java step is to register the ViewManager to the application, this happens in a similar way to Native Modules, via the applications package member function
requireNativeComponent commonly takes two parameters, the first is the name of the native view and the second is an object that describes the component interface. The component interface should declare a friendly
name for use in debug messages and must declare the
propTypes reflected by the Native View. The
requireNativeComponent. This is illustrated in the
MyCustomView example below.
The event name
topChange maps to the
UIManagerModuleConstants.java). This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
Note the use of
nativeOnly above. Sometimes you'll have some special properties that you need to expose for the native component, but don't actually want them as part of the API for the associated React component. For example,
Switch has a custom
onChange handler for the raw native event, and exposes an
onValueChange handler property that is invoked with just the boolean value rather than the raw event (similar to
onChangeMessage in the example above). Since you don't want these native only properties to be part of the API, you don't want to put them in
propTypes, but if you don't you'll get an error. The solution is simply to call them out via the
Improve this page by sending a pull request!