Storyteller Jetpack Compose Wrapper

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.

Getting Started

Resources

How to Add the SDK to Your Project

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].

SDK Dependencies

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")

SDK Installation

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.

  1. 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 not buildscript

       // ...
       allprojects {
          repositories {
             google()
             mavenCentral()
             maven {
                 url 'https://www.myget.org/F/storyteller-android-sdk/maven'
             }
         }
       }
    
  2. 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")
         }
    
    
  3. Sync your project with Gradle files

  • Android Studio

Usage

  1. 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.

  2. 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:

    1. StorytellerRowView
    2. StorytellerGridView
    3. StorytellerClipsRowView
    4. StorytellerClipsGridView
  3. Using the Storyteller Composables

    You can always access the composables at any time using the controller instance.

    1. 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
      
    2. Or using the more general way.

      controller.forEach { it.reloadData() } // reload all the composables in the current controller
      
    3. 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.

  4. 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 and setCategories methods to set the collection and categories shorthand methods, rather than forEach. This is because the shorthand methods will make sure that they are called on correct view types.

Storyteller Compose Controller

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.

StorytellerGridView

The StorytellerGridView is a wrapper to the StorytellerGridView view from the Storyteller SDK.

Usage in Compose

@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()
  }
}

StorytellerRowView

The StorytellerRowView is a wrapper to the StorytellerRowView view from the Storyteller SDK.

Usage in Compose

@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()
  }
}

StorytellerClipsGridView

The StorytellerClipsGridView is a wrapper to the StorytellerClipsGridView view from the Storyteller SDK.

Usage in Compose

@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()
  }
}

StorytellerClipsRowView

The StorytellerClipsRowView is a wrapper to the StorytellerClipsRowView view from the Storyteller SDK.

Usage in Compose

@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()
  }
}

What's New

1.0.0 - 01/01/23

  • Initial release
PREVIOUS
Forward Arrow