メインコンテンツまでスキップ

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()
}
}
}
この{Type}は役に立ちましたか?