Skip to content

Theming#

The Citymapper SDK offers basic theming capabilities to help it fit in with your app. You can change the following aspects:

  • Fonts
  • Colors
  • Limited icons and images

Default Theme Settings#

Main text styles

ETA & Duration styles

Colours

Android#

All SDK UI elements are isolated from the surrounding Activity/Fragment's theme. To customise the UI, add a citymapperSdkTheme attribute in your Activity's theme which references a custom SDK theme. This custom theme must inherit from Base.Theme.CitymapperSdk

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="citymapperSdkTheme">@style/MyCitymapperSdkTheme</item>
</style>

<style name="MyCitymapperSdkTheme" parent="Base.Theme.CitymapperSdk">
    <item name="colorPrimary">@color/...</item>
    <item name="cmContentColor">@color/...</item>
    <item name="cmTextAppearanceH1">@style/...</item>
    <item name="cmTextAppearanceH2">@style/...</item>
    <item name="cmTextAppearanceDisplay">@style/...</item>
    <item name="cmTextAppearanceBody1">@style/...</item>
    <item name="cmTextAppearanceBody2">@style/...</item>
    <item name="cmTextAppearanceBody3">@style/...</item>
    <item name="cmTextAppearanceDurationLargeDigit">@style/...</item>
    <item name="cmTextAppearanceDurationMediumDigit">@style/...</item>
    <item name="cmTextAppearanceDurationSmallDigit">@style/...</item>
    <item name="cmTextAppearanceDurationLargeMin">@style/...</item>
    <item name="cmTextAppearanceDurationMediumMin">@style/...</item>
    <item name="cmTextAppearanceDurationSmallMin">@style/...</item>
    <item name="cmTextAppearanceStartEndPin">@style/...</item>
    <item name="cmStartEndMapPinBackgroundColor">@color/...</item>
    <item name="android:listDivider">@drawable/...</item>
    <item name="cmBottomSheetCornerRadius">@dimen/...</item>
    <item name="cmLiveIndicatorStyle">@style/...</item>
    <!-- cmPriceViewStyle accepts arbitrary TextView styling -->
    <item name="cmPriceViewStyle">@style/...</item>
    <!-- See below for accepted background styling attributes -->
    <item name="cmDisruptionBackgroundStyle">@style/...</item>
    <item name="cmDeparturesBackgroundStyle">@style/...</item>
    <!-- android:background is the only currently supported attribute for the Route Detail header style -->
    <item name="cmRouteDetailHeaderStyle">@style/...</item>
    <item name="cmRouteDetailSheetBackgroundColor">@color</item>
    <item name="cmRouteDetailBestExitBackgroundStyle">@style/...</item>
    <item name="cmRouteDetailBestExitIconColor">@color/...</item>
    <item name="cmRouteDetailWalkToStationIcon">@drawable/...</item>
    <item name="cmRouteDetailChangePlatformIcon">@drawable/...</item>
    <item name="cmRouteDetailBestSectionBackgroundStyle">@style/</item>
    <item name="cmRouteSummaryWalkIconColor">@color/...</item>
    <item name="cmRouteSummaryTextColor">@color/...</item>
    <item name="cmRouteSummaryServiceSeparatorColor">@color/..</item>
    <item name="cmRouteSummaryLegSeparatorColor">@color/..</item>
    <item name="cmRouteSummaryGenericVehicleIconColor">@color/..</item>
    <item name="cmRouteSummaryWalkIcon">@drawable/...</item>
    <item name="cmRouteSummaryLongWalkIcon">@drawable/...</item>
    <item name="cmDirectionsListBackgroundColor">@color/...</item>
    <item name="cmDirectionsInstructionCardCornerRadius">@dimen/...</item>
    <item name="cmDirectionsFutureInstructionIconBackgroundCornerRadius">@dimen/...</item>
    <item name="cmDirectionsNextInstructionIconBackgroundCornerRadius">@dimen/...</item>
    <item name="cmDirectionsInstructionIconBackgroundColor">@color/...</item>
    <item name="cmDirectionsInstructionIconTint">@color/...</item>
    <item name="cmDirectionsMapButtonIconTint">@color/...</item>
    <item name="cmDirectionsInstructionTooltipBackgroundCornerRadius">@dimen/...</item>
    <item name="cmWalkOnlyIcon">@drawable/...</item>
    <item name="cmBikeIcon">@drawable/...</item>
    <item name="cmScooterIcon">@drawable/...</item>
    <item name="cmTransportTypeNameWalk">@string/...</item>
    <item name="cmTransportTypeNameBike">@string/...</item>
    <item name="cmTransportTypeNameScooter">@string/...</item>
    <item name="cmArrivalTickIcon">@drawable/...</item>
    <item name="cmArrivalTickButtonBackgroundColor">?attr/colorPrimary</item>
    <item name="cmArrivalTickButtonTintColor">#FFFFFF</item>
</style>

Styles which affect the background of Route Detail elements, e.g. cmDisruptionBackgroundStyle, support setting the color and stroke color of the background. For example:

<style name="MyTheme.Departures.Background" parent="">
    <item name="android:color">#F8F8F8</item>
    <item name="android:strokeColor">#E5E5E5</item>
</style>

iOS#

In Swift, you can define a struct for your theme that fulfills the Theme protocol, allowing you to define various fonts, colors, and image assets to be used in the UI. You can then pass this struct to the initializer of Route List view controller or Route Detail view controller along with the Route(s) to display.

// MARK: - Main Theme Protocol

public protocol Theme {
    var textAppearance: TextAppearance { get }
    var colorTheme: ColorTheme { get }
    var assetTheme: AssetTheme { get }

    // Element-based
    var routeSummaryStyle: RouteSummaryStyle { get }
    var largeDurationStyle: DurationStyle { get }
    var mediumDurationStyle: DurationStyle { get }
    var smallDurationStyle: DurationStyle { get }
    var routeListSeparatorStyle: ListSeparatorStyle { get }
    var routeDetailsSeparatorStyle: ListSeparatorStyle { get }
    var priceViewStyle: PriceViewStyle { get }
    var departureListStyle: DepartureListStyle { get }
    var routeDetailSheetStyle: RouteDetailSheetStyle { get }
    var disruptionBoxStyle: DisruptionBoxStyle { get }
    var bestExitTipBoxStyle: BestExitTipBoxStyle { get }
    var mapStyle: MapStyle { get }

    var backgroundCornerRadius: CGFloat { get }

    var nextTurnStyle: NextTurnStyle { get }

    var navigationListStyle: NavigationListStyle { get }
    var navigationMapButtonStyle: FloatingButtonsStyle { get }
}

public protocol SelectableListStyle {
    var selectedItemBackgroundColor: UIColor { get }
    var unselectedItemBackgroundColor: UIColor { get }
}

public protocol NavigationListStyle: SelectableListStyle {
    var listBackgroundColor: UIColor { get }
    var listHeaderCornerRadius: CGFloat { get }
    var headerTopCornerRadius: CGFloat { get }
    var headerExtensionBoxCornerRadius: CGFloat { get }
    var headerExtensionBoxBackgroundColor: UIColor { get }

    var selectedItemCornerRadius: CGFloat { get }
    var unselectedItemCornerRadius: CGFloat { get }

    var instructionCardCornerRadius: CGFloat { get }
    var instructionIconTintColor: UIColor? { get }
    var instructionIconBackgroundColor: UIColor { get }

    var nextInstructionIconCornerRadius: CGFloat { get }
    var futureInstructionIconCornerRadius: CGFloat { get }
}

public protocol RouteDetailSheetStyle {
    var backgroundColor: UIColor { get }
    var headerBackgroundColor: UIColor { get }
}

public protocol NextTurnStyle {
    var backgroundColor: UIColor { get }
    var cornerRadius: CGFloat { get }
}

public protocol FloatingButtonsStyle {
    var tintColor: UIColor { get }
    var textStyle: TextStyle { get }
}

public protocol BoxWithOutlineStyle {
    var backgroundColor: UIColor { get }
    var outlineColor: UIColor { get }
}

public protocol DepartureListStyle: BoxWithOutlineStyle {}

public protocol DisruptionBoxStyle: BoxWithOutlineStyle {}

public protocol BestExitTipBoxStyle: BoxWithOutlineStyle {
    var iconTintColor: UIColor { get }
}

public protocol RouteSummaryStyle {
    var walkIconColor: UIColor { get }
    var serviceSeparatorColor: UIColor { get }
    var legSeparatorColor: UIColor { get }
    var genericVehicleIconColor: UIColor { get }
    var serviceNameColor: UIColor { get }
    var serviceGroupBorderColor: UIColor { get }
}

// MARK: - Main Font Theme Protocol

public protocol TextAppearance {
    var H1: TextStyle { get }
    var H2: TextStyle { get }
    var display: TextStyle { get }
    var body1: TextStyle { get }
    var body2: TextStyle { get }
    var body3: TextStyle { get }
}

public struct TextStyle {
    public let font: UIFont
    public let textColor: UIColor
}

public protocol DurationStyle {
    var prefixTextStyle: TextStyle { get }
    var digitTextStyle: TextStyle { get }
    var minTextStyle: TextStyle { get }
    var separatorTextStyle: TextStyle { get }
    var allCaps: Bool { get }
}

// MARK: - Main Color Theme Protocol

public protocol ColorTheme {
    var colorPrimary: UIColor { get }
    var contentColor: UIColor { get }
    var contentBackgroundColor: UIColor { get }
}

// MARK: - Main Asset Theme Protocol

public protocol AssetTheme {
    var defaultLiveBlip: ImageAsset { get }
    var normalWalkIcon: ImageAsset { get }
    var longWalkIcon: ImageAsset { get }
    var walkOnlyIcon: ImageAsset { get }
    var scooterIcon: ImageAsset { get }
    var bikeIcon: ImageAsset { get }
    var inStationWalkIcon: ImageAsset { get }
    var toStationWalkIcon: ImageAsset { get }

    var stringsTheme: LocalisableStringsTheme { get }
}

public protocol LocalisableStringsTheme {
    var walkString: LocalizableString { get }
    var bikeString: LocalizableString { get }
    var eScooterString: LocalizableString { get }
}

public protocol LocalizableString {
    var localizedText: String { get }
}

public enum LocalizableStringFactory {

    static func localizableString(name: String,
                                  bundle: Bundle) -> LocalizableString {
        BasicLocalizableString(name: name,
                               bundle: bundle)
    }
}