Skip to main content

Search Card customization

The content of the card is divided into functional blocks, and you can asynchronously hide or modify these blocks (green blocks on the image) in a stream like what is available in Kotlin Flow.

For constructing the card content, the following builder class is used:

class Builder {

private var arrivalInformation: ViewBlock = DefaultViewBlock
private var weather: ViewBlock = DefaultViewBlock
private var rating: ViewBlock = DefaultViewBlock
private var openHours: ViewBlock = DefaultViewBlock
private var chargingInformation: ViewBlock = DefaultViewBlock
private var destinationInformation: ViewBlock = DefaultViewBlock
private var destinationFeedback: ViewBlock = DefaultViewBlock
private val orderedViews: MutableMap<Int, ViewBlock> = mutableMapOf()
}

ViewBlock is an abstract class with several implementations:

  • HiddenViewBlock: This block remains hidden.
  • DefaultViewBlock: Default UI will be used.
  • AndroidViewBlock: Creates a view based on View.
  • ComposeViewBlock: Creates a view based on @Composable function.
  • LoadingViewBlock: This block can be used to display a loading indicator while the content is being fetched.

Customization Process

Customization is available through the DashLayoutEditor class, which can be accessed via DashMainFragment using the layoutEditor method.

fragment.layoutEditor {
// logic for UI customization
}

DashLayoutEditor provides two methods for customization:

  • updateDestinationPreviewLayout: Updates the destination preview layout using the provided modification block.
  • defaultDestinationPreviewLayout: Resets the destination preview layout to its default state.

updateDestinationPreviewLayout uses block: suspend CollectorBuilder.(DestinationResult) -> Unit as a modification block where CollectorBuilder is a helper class for creating DestinationPreviewLayout.Builder in a simplified DSL format.

interface CollectorBuilder {

/**
* Assigns the DestinationPreviewLayout using the provided modification block.
*/
suspend infix fun assign(block: suspend DestinationPreviewLayout.Builder.() -> Unit)

/**
* Assigns the DestinationPreviewLayout using the default settings.
*/
suspend fun assignDefault()
}

CollectorBuilder uses DestinationResult as input to fill UI state.

Example Usage

private suspend fun DashNavigationFragment.setSingleCustomView() = editLayout {
updateDestinationPreviewLayout { destinationResult ->
// Set loading state
assign {
arrivalInformation(LoadingViewBlock)
destinationInformation(LoadingViewBlock)
}

// Call suspend function
val isCustomUiRequired = checkIfUiRequired(destinationResult)
if (isCustomUiRequired) {
assign {
custom(
DestinationPreviewLayout.Order.Weather,
DestinationPreviewLayout.RelativePosition.Below,
AndroidViewBlock(factory = { context -> AppCompatTextView(context) }) { view ->
view.text = "Show custom loading"
for (i in 1..20) {
delay(50) // Simulate loading via coroutine delay
view.text = "Loading${".".repeat(i)}"
}
view.text = "Custom view is loaded"
},
)
}
} else {
assignDefault()
}
}
}
Was this page helpful?