Custom Modules, Android
  • 06 Jul 2023
  • 4 Minutes to read
  • Contributors
  • Dark
    Light

Custom Modules, Android

  • Dark
    Light

Article summary

Summary

All prebuild and custom modules are classes that must inherit from TicketSDKModule. To facilitate the creation of these modules, we created the class ModuleBase, which has a collection of predefined views (header and button section), and a collection of actions to be captured by the events.

To start, first add a TicketsModuleDelegate object to TicketsSDKSingleton.moduleDelegate

TicketsSDKSingleton.moduleDelegate = object : TicketsModuleDelegate {
    override fun getCustomModulesLiveData(order: Order): LiveData<List<TicketsSDKModule>> {
        val modules: ArrayList<TicketsSDKModule> = ArrayList()
        modules.add(getCustomModule(activity))
        return MutableLiveData(modules)
    }

    override fun userDidPressActionButton(buttonTitle: String?, callbackValue: String?, eventOrders: EventOrders?) {
        //buttonTitle: text inside the Material Button
        //callbackValue: LeftClick, MiddleButton or RightClick
        Log.d("userDidPressAction", eventOrders.toString())
    }
}

Modules are built and returned in getCustomModule(context: Context): ModuleBase

fun getCustomModule(context: Context): ModuleBase {
    // create a module base class
    val moduleBase = ModuleBase(context)

    // build a view
    val view = View(context)
    
    // add the created view to the header container
    moduleBase.setHeader(view)
    
    view.setBackgroundColor(ContextCompat.getColor(context, R.color.tickets_tm_brand_blue))
    (view.layoutParams as ConstraintLayout.LayoutParams).apply {
        height = context.dpToPx(200f).roundToInt()
    }

    // add text to the left button
    moduleBase.setLeftButtonText("One")
    
    // add text to the middle button
    moduleBase.setMiddleButtonText("Two")
    
    // add text to the right button
    moduleBase.setRightButtonText("Three")

    // return the created moduleBase object
    return moduleBase
}

Output
custom_module_example_1.jpg

While optional, the Header is the most easily visible component of a Module.

A Header is simply a container class (ConstraintLayout) around the Module. The view you add via setHeader function, will replace all the content inside this container.

Size

The Header is automatically resized to the width of the user's phone, so you can only really control the height. This is done by setting the height of the view by retrieving its layout parameters.

In the example, it is created a custom module, where the header is a default view with a background color and 200 dp as height.

fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)

    // build a view
    val view = View(context)
    
    // add the default view to the header container
    moduleBase.setHeader(view)
    
    // in this example, we define a background color to the view, and add 200dp to the height
    view.setBackgroundColor(ContextCompat.getColor(context, R.color.tickets_tm_brand_blue))
    (view.layoutParams as ConstraintLayout.LayoutParams).apply {
        height = context.dpToPx(200f).roundToInt()
    }

    moduleBase.setLeftButtonText("One")
    moduleBase.setMiddleButtonText("Two")
    moduleBase.setRightButtonText("Three")
    
    return moduleBase
}

Output
custom_module_example_1.jpg

Header Custom Image

Headers can also be created with an ImageView (as a convenience). The aspect ratio of the Header is inherited from the size of the image.

  • Build a module with an Image header, aspect ratio is defined by Image size
fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)

    // create an imageview
    val view = ImageView(context)
    
    // set image to the view created
    view.setImageResource(R.drawable.tacos)
    
    // set the view into the header
    moduleBase.setHeader(view)

    moduleBase.setLeftButtonText("One")
    moduleBase.setMiddleButtonText("Two")
    moduleBase.setRightButtonText("Three")

    return moduleBase
}

Output:
custom_module_example_2.jpg

Header Custom Layout

Headers are view containers where you can add multiple views. To do so, you can add a custom layout displaying multiple views as text and image views, among others.

fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)
    
    // set custom layout into the header
    moduleBase.setHeader(R.layout.custom_module)

    moduleBase.setLeftButtonText("One")
    moduleBase.setMiddleButtonText("Two")
    moduleBase.setRightButtonText("Three")

    return moduleBase
}

Output:
custom_module_example_3.jpg

Views can also be referenced inside the moduleBase, so that their value can be modified as needed.

fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)

    moduleBase.setHeader(R.layout.custom_module)

    // retrieve the top left textview defined on the layout
    val textView = moduleBase.findViewById<TextView>(R.id.top_left)
    // modify te text of the textview
    textView.text = "Left Top"

    // retrieve the imageview at the center of the layout
    val imageView = moduleBase.findViewById<ImageView>(R.id.front_image)
    // modify the color of the background of the image view.
    imageView.setBackgroundColor(ContextCompat.getColor(context, R.color.red))

    moduleBase.setLeftButtonText("One")
    moduleBase.setMiddleButtonText("Two")
    moduleBase.setRightButtonText("Three")

    return moduleBase
}

Output:
custom_module_example_4.jpg

Buttons

Buttons are assigned Actions that occur when the button is pressed.

Currently, only two Actions are supported:

  1. add a custom listener for each of the buttons defined.
  2. callback to module delegate (inside your app)

Note that a Module can contain a Header with no Buttons, or Buttons with no Header.

Button Action: Custom listeners

When the user presses the button, the listener method on the button will be called.

  • Build three buttons (with no header):
fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)

    moduleBase.setLeftButtonText("One")
    moduleBase.setMiddleButtonText("Two")
    moduleBase.setRightButtonText("Three")
    
    // added listener to handle the click event on the left button
    moduleBase.setLeftClickListener { Log.d("Module Base", "Left button clicked") }
    // added listener to handle the click event on the middle button
    moduleBase.setMiddleClickListener { Log.d("Module Base", "Left button clicked") }
    // added listener to handle the click event on the right button
    moduleBase.setRightClickListener { Log.d("Module Base", "Left button clicked") }

    return moduleBase
}

You can fully customize the listener, like open a new app using a given url.

  • Build one button, which launches a webpage.
fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)
    moduleBase.setLeftButtonText("Open web page")
    moduleBase.setLeftClickListener {
        context.startActivity(TmxWebUriHelper.openWebUriWebView(context, "https://www.ticketmaster.com"))
    }
    return moduleBase
}

Button Actions: Callback

When the user presses a button, the callback method userDidPressActionButton(buttonTitle: String?, callbackValue: String?, eventOrders: EventOrders?) inside the TicketsModuleDelegate object will be called.

To enable the callback on the buttons, you will need to follow two steps.

  1. On the creation of the custom module, add a listener to each button you want to enable.
fun getCustomModule(context: Context): ModuleBase {
    val moduleBase = ModuleBase(context)
    moduleBase.setLeftButtonText("First")
    moduleBase.setRightButtonText("Open web page")
    // you can add an empty listener
    moduleBase.setLeftClickListener {}
    // or add a listener with its own logic
    moduleBase.setRightClickListener { context.startActivity(TmxWebUriHelper.openWebUriWebView(context, "https://www.ticketmaster.com")) }
    return moduleBase
}
  1. Handle the click event on the function userDidPressActionButton(...)
override fun userDidPressActionButton(buttonTitle: String?, callbackValue: String?, eventOrders: EventOrders?) {
    buttonTitle?.let { title ->
        if (title == "Open web page" || title == "First") {
            callbackValue?.let { callback ->
                when (callback) {
                    "LeftClick" -> {
                        Toast.makeText(context, "Left button clicked", Toast.LENGTH_SHORT).show()
                    }
                    "RightClick" -> {
                        TmxWebUriHelper.openWebUriWebView(context, "https://www.ticketmaster.com")
                    }
                    else -> {
                        Toast.makeText(context, "No handled event", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }
    }
}

Pre-Built Modules

A few basic modules have already been created for you, see: PreBuilt Modules, Android

API Documentation

For more options see: API Documentation, Android


Was this article helpful?