Skip to main content

Compatibility with Custom Views

caution

This section contains information about the old Java Spec API. For new development, the Primitive Components is a recommended way to migrate from custom Views to Litho Components.

This page details how to migrate custom Views to Litho Components when the existing widgets cannot be composed to achieve the UI you want.

Some cases when you might need this migration include:

  • Custom design systems with specialised widgets or measuring logic.
  • Displaying Video, for which Litho doesn't provide a widget.
  • Migrating a surface to Litho incrementally when you need to maintain a hybrid View-Component UI.

Views to Components​

To learn how you can bridge a custom View or Drawable to a Component, follow the Mount Specs page (in the Codege APIs secton).

info

Bridging Views into Components is currently only supported through the Codegen MountSpec API.

You can compose MountSpec Components as you would compose any other KComponents, but they are instantiated using the Codegen Components Builder pattern. Consider the following MountSpec Component:

@MountSpec
object CircularImageSpec {

@OnCreateMountContent
fun onCreateMountContent(androidContext: Context): CustomImageView {
return CustomImageView(androidContext)
}

@OnMount
fun onMount(context: ComponentContext, image: CustomImageView, @Prop url: String) {
image.setUrl(url)
}
}

You can create an instance of CircularImage in the render() method of a KComponent using its Builder:

override fun ComponentScope.render(): Component {
return CircularImage.create(context)
.widthDip(100f)
.heightDip(100f)
.marginDip(YogaEdge.TOP, 20f)
.url("image/url")
.build()
}

Codegen component wrappers​

A common pattern for using Codegen MountSpec Components in KComponents is to wrap them in a ResourcesScope extension function and call that instead of the Builder to create the Component.

This gives uniformity to your KComponent code as well as enabling you to seamlessly convert the Codegen MountSpec Components to a Kotlin DSL API when it becomes available without updating the existing usages.

inline fun ResourcesScope.CircularImage(
url: String,
style: Style? = null,
) = CircularImage.create(context).url(url).kotlinStyle(style).build()

After creating the wrapper, you can use a CircularImage Component as follows:

override fun ComponentScope.render(): Component {
return CircularImage(
url = "image/url", style = Style.width(100.dp).height(100.dp).margin(top = 10.dp))
}