This is a developers' guide for setting up Storyteller Compose SDK for native Android apps. This guide will cover the basic technical steps for integrating Storyteller Compose SDK into your app.
Before you can add the Android SDK to your app, you will need to obtain an API Key. This is a secret key used to authenticate the SDK in your app. Throughout this document it will be marked as [APIKEY]
.
Currently the Compose Android SDK contains the following dependencies:
implementation(platform("androidx.compose:compose-bom:2022.11.00"))
implementation("androidx.activity:activity-compose:1.6.1")
The Compose SDK can be included in your project using Gradle. It is recommended to use Android Studio. If you are having problems with configuring your build, check out the Android Studio guide or Gradle guides.
Add the maven repository for the SDK in the Project build.gradle
file (MyAwesomeApp/build.gradle
), under the allprojects
section
Note: make sure it is added to
allprojects
, and notbuildscript
// ...
allprojects {
repositories {
google()
mavenCentral()
maven {
url 'https://www.myget.org/F/storyteller-android-sdk/maven'
}
}
}
Modify the app Module build.gradle
file (MyAwesomeApp/app/build.gradle
)
// ...
android {
// ...
}
dependencies {
// ...
def storyteller_compose_version = "1.0.0"
implementation(group: "Storyteller", name: "sdk-compose", version: "$storyteller_compose_version")
}
Sync your project with Gradle files
Android Studio
At first we will need a controller, which will be used to track composables, for ease of use and to avoid memory leaks. Then we will need to bind the controller to the hosting activity lifecycle, so we will need to create a custom ComponentActivity
and override the onCreate
method.
class MainActivity : ComponentActivity() {
private lateinit var controller: StorytellerComposeController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
controller = StorytellerComposeController().bind(this)
// ...
}
}
Note: Don't worry about doing anything in the
onDestroy
method, the controller will handle it for you.
Storyteller Composables Now it's time to add the Storyteller Composables to your app. The Storyteller Composables are the building blocks of the Storyteller SDK. They use the same names as the normal views and you can see both in the following image. You should pick the green one (composable).
StorytellerRowView(
modifier = modifier,
tag = type.tag, // tag to identify this composable
controller = controller // controller to control the state of the composable mainly we should define one per activity
) { // the configuration block
delegate = listViewDelegate
cellType = StorytellerListViewCellType.SQUARE
categories = // provide the categories
reloadData() // we want to reload data when the backing view is initialized
}
We have the following composable types available:
Using the Storyteller Composables
You can always access the composables at any time using the controller
instance.
Reload Data for all views:
We've added a helper to reload all Storyteller views attached to the same controller. So if you want to reload the data of a StorytellerRowView
you can do the following:
controller.reloadData() // reload all the composables in the current controller
Or using the more general way.
controller.forEach { it.reloadData() } // reload all the composables in the current controller
Or if you want to reload a specific composable you can do the following:
controller.reloadData("tag-1")
You can use different variations to trigger actions on composables. You can pass nothing in the list and it will trigger the action on all composables, or you can pass a list of tags and it will trigger the action on all composables with the given tags.
Setting categories and collections
You can use the specific method to set collection as the following:
controller.setCollection { "collection-1" } // set the collection for all the composables in the current controller
controller.setCollection("tag-1") { "collection-1" } // set the collection for the composables with the given tag
You can use the specific method to set categories as the following:
controller.setCategories { listOf("category-1", "category-2") } // set the categories for all the composables in the current controller
controller.setCategories("tag-1") { listOf("category-1", "category-2") } // set the categories for the composables with the given tag
Note: Always use the
setCollection
andsetCategories
methods to set the collection and categories shorthand methods, rather thanforEach
. This is because the shorthand methods will make sure that they are called on correct view types.
The StorytellerComposeController
is the bridge between both the View and Compose ecosytems.
A controller is used to track, access and destroy composables upon need to avoid memory leaks. It also needs to be bound to the hosting activity lifecycle.
We recommend creating the controller in the hosting activity, then calling the bind
method inside Activity's onCreate
, and finally, create a getter for it to be used when creating composables.
class MainActivity : ComponentActivity() {
private lateinit var controller: StorytellerComposeController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
controller = StorytellerComposeController().bind(this)
// ...
}
}
Note: Don't worry about doing anything in the
onDestroy
method, the controller will handle it for you.
The StorytellerGridView
is a wrapper to the StorytellerGridView
view from the Storyteller SDK.
@Composable
fun GridItem(
modifier: Modifier = Modifier,
type: StorytellerType.StorytellerGrid,
controller: StorytellerComposeController,
listViewDelegate: StorytellerListViewDelegate,
) {
StorytellerGridView(
modifier = modifier,
tag = type.tag,
controller = controller
) {
delegate = listViewDelegate
cellType = StorytellerListViewCellType.SQUARE
categories = type.categories
reloadData()
}
}
The StorytellerRowView
is a wrapper to the StorytellerRowView
view from the Storyteller SDK.
@Composable
fun RowItem(
modifier: Modifier = Modifier,
type: StorytellerType.StorytellerRow,
controller: StorytellerComposeController,
listViewDelegate: StorytellerListViewDelegate,
) {
StorytellerRowView(
modifier = modifier,
tag = type.tag,
controller = controller
) {
delegate = listViewDelegate
cellType = StorytellerListViewCellType.SQUARE
categories = type.categories
reloadData()
}
}
The StorytellerClipsGridView
is a wrapper to the StorytellerClipsGridView
view from the Storyteller SDK.
@Composable
fun ClipsGridItem(
type: StorytellerType.StorytellerClipsGrid,
controller: StorytellerComposeController,
listViewDelegate: StorytellerListViewDelegate
) {
StorytellerClipsGridView(
tag = type.tag,
controller = controller
) {
delegate = listViewDelegate
cellType = StorytellerListViewCellType.ROUND
collection = type.collection
reloadData()
}
}
The StorytellerClipsRowView
is a wrapper to the StorytellerClipsRowView
view from the Storyteller SDK.
@Composable
fun ClipsRowItem(
type: StorytellerType.StorytellerClipsRow,
controller: StorytellerComposeController,
listViewDelegate: StorytellerListViewDelegate
) {
StorytellerClipsRowView(
tag = type.tag,
controller = controller
) {
delegate = listViewDelegate
cellType = StorytellerListViewCellType.ROUND
collection = type.collection
reloadData()
}
}