DivKit builds native views from JSON data.
JSON → DivData → Android View
-
JSON – raw data with templates in DivKit format (see DivKit schema).
-
DivData – data objects parsed from JSON.
-
Android View - Plain old Android view system
build.gradle
– main Android Studio project with everything Android related.
Use divkit-demo-app
configuration to build and launch our demo app.
sample
– sample project with a very simple DivKit integration
Documentation. Medium tutorial. Habr tutorial.
Telegram: News | English-speaking chat | Чат на русском.
To get started with drawing your first view, follow these three simple steps:
- Initialize the Configuration: Begin by creating an instance of
DivConfiguration
. The only required parameter isDivImageLoader
. You have the option to implement your own custom implementation of this interface or use one of our implementations:PicassoDivImageLoader
orGlideImageLoader
. For an example of how to create aDivConfiguration
in our demo app, you can refer to this link. Each parameter ofDivConfiguration#builder
will be described below. - JSON-layout parsing: A div-layout comprises two crucial parts:
"templates"
and"cards"
. In our example, both parts are contained within a single JSON-file. However, in your code, you are free to separate them if it suits your needs. Your card parsing method might resemble something along these lines:
fun JSONObject.asDiv2DataWithTemplates(): DivData {
val templates = getJSONObject("templates")
val card = getJSONObject("card")
val environment = DivParsingEnvironment(ParsingErrorLogger.LOG)
environment.parseTemplates(templates)
return DivData(environment, card)
}
You are free to use our examples of div layouts: sample cards and cards for testing.
- Adding Div2View to your layout is pretty simple:
val div2View = Div2View(Div2Context(baseContext = this, configuration = config))
yourViewGroup.addView(div2View)
div2View.setData(divData, DivDataTag("your_unique_tag_here"))
Congrats, you just drawn your fist Div2View! To understand why DivDataTag is so important check section about Div2Logger.
To learn more about actions, please refer to this section in our documentation. DivKit will automatically handle all actions defined in our schema. However, you might want to trigger custom code from your layout. To achieve this, you can implement your own DivActionHandler
interface.
As an example, you can refer to our implementations of implementation in the SamplesActivity from our demo app. Don't forget to call super.handleAction
if action wasn't handled by your custom handler!
Interface Div2Logger
is pretty simple. When you define your implementation, DivKit will log each action for you. Additionally, it's essential to note that you can set the DivDataTag
to distinguish between different Div2View
in your logs. You can also specify the "id"
field when describing views within your layout.
As an example you can reffer to our implementation of DemoDiv2Logger.
You can define any custom view you want, set some custom-name and then use in inside your layout.
As an example, you can refer to our video-custom implementation. Here we define implementation of custom adapter. Take note of the method VideoCustomAdapter#isCustomTypeSupported
, which specifies that only custom elements with the type "custom_video"
can be handled by this adapter. Once you've created the VideoCustomAdapter
, simply pass it to DivConfiguration, and your video_custom element is ready to be used within your JSON layout.
Custom View Groups
The implementation does not differ significantly from the implementation of regular custom views. The only notable difference is that you will need to extend the handling of the createView
and bindView
events deeper down the hierarchy of views. Fortunately, we've introduced a static method, DivCustomContainerViewAdapter#getDivChildFactory
, which can create and bind these wondrous views. For instance, if there are some items in your layout:
{
"type": "custom",
"id": "new_custom_container_1",
"items": [
{
"type": "text",
"news_item_text": "This is div-text item 1"
},
{
"type": "text",
"news_item_text": "This is div-text item 2"
}
],
"custom_type": "new_custom_container_1"
}
You can override DivCustomContainerViewAdapter#CreateView
like this:
div.items!!.forEach {
val childDivView = getDivChildFactory(divView).createChildView(
it,
DivStatePath.fromState(divView.id),
divView
)
(customView as ViewGroup).addView(childDivView)
}
And then bind child items inside DivCustomContainerViewAdapter#BindView
:
for (i in div.items!!.indices) {
val childDivView = customView.getChildAt(i)
val childDiv = div.items!![i]
getDivChildFactory(divView).bindChildView(
childDivView,
childDiv,
DivStatePath.fromState(divView.id),
divView
)
}
You can implement your own DivTypefaceProvider and use them inside our layout. As an example, you can refer to YandexSansDisplayDivTypefaceProvider. Then we put {"display" to YandexSansDisplayDivTypefaceProvider()}
to DivConfiguration.Builder#typefaceProfiders
. And from now on you can set "font_family": "display"
to text in your json. If you want to override standard font, just pass your typeface provider to DivConfiguration.Builder#typefaceProfider
.
In DivConfiguration.Builder#supportHyphenation
, you can enable word wrap support by setting the Hyphenation option. Please note that this function is disabled by default.
In your layout, you can easily set up a pop-up menu by specifying a div-action
for the desired div, which includes the menu_items
field.
From a coding perspective, in DivConfiguration.Builder#overrideContextMenuHandler
you can just turn off them. You can use it to determine whether you want to display as custom menus (by capturing the necessary actions in DivActionHandler
).
By default, longtap_actions events do not propagate (they work on the main container, but are not captured by child elements) if the nested element has its own actions. This behavior aligns with the standard logic of Android and iOS platforms.
However, if you have a specific need for longtap_actions to propagate to all child elements you can change this by using the DivConfiguration.Builder#enableLongtapActionsPassingToChild
method.