Skip to content

2: Usage

Kieron Quinn edited this page Jun 27, 2021 · 5 revisions

After you have set up MonetCompat, there are a number of options of how to apply the colors.

Semi-automatically

The easiest way, if you wish to use all the default options, is to extend from MonetFragment and call applyMonetRecursively() on your root view after it's created:

class MainFragment: MonetFragment(R.layout.fragment_main){

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.applyMonetRecursively()   
    }

}

Assuming you have recreateMode enabled in your activity (defaults to enabled), this will automatically apply Monet colors to the supported "Auto Themeable Views" (full list of supported View types). Note that, because this is done recursively (ie. by looping through your layout tree), it may cause brief lag with complex layouts. If you have a complex layout and only a few Views need theming, you may wish to use the manual method detailed below.

Setting which Views to theme

Auto Themeable Views, as the name suggests, are Views that MonetCompat can apply Monet colors to automatically. However, you may not want Monet to be applied to specific View types supported, or would like to add your own View types to be themed in the recursive call. This is also supported, by passing arguments to applyMonetRecursively():

//Only theme Checkboxes and Buttons
view.applyMonetRecursively(themeableViews = MonetAutoThemeableViews.CHECKBOX, MonetAutoThemableViews.BUTTON)

Note: If you are not using the Material library, you should always pass MonetAutoThemableViews.ALL_NO_MATERIAL, or a collection of types that do not contain _MATERIAL

themeableViews is a vararg, so allows you to list your preferred View types. Note that views from the Material library are separate, and must be specified (eg. MonetAutoThemableViews.CHECKBOX_MATERIAL) as well as the normal types.

To add your theming logic for custom Views, pass a list of handlers to the customThemables argument, for example:

class MainFragment: MonetFragment(R.layout.fragment_main){

    // Theme all TextViews by setting their text color to the Monet accent color
    private val textViewAccentTheming = customThemeableView<TextView>(TextView::class, AppCompatTextView::class, MaterialTextView::class){ textView, monet ->
       textView.setTextColor(monet.getAccentColor(textView.context))
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.applyMonetRecursively(customThemeables = listOf(textViewAccentTheming))
    }

}

Manually

To theme a view manually, you will need access to the instance of MonetCompat. This can be got by calling MonetCompat.getInstance(), so long as MonetCompat.setup(Context) has been called previously (this is handled automatically if you are using MonetCompatActivity as detailed on the setup page)

Supported Views

For View types supported by MonetAutoThemeableView, simply call the applyMonet() extension method on the View, and Monet colors will be applied.

Note: The View extension does not automatically re-apply colors if you are not using recreate mode, so you will need to re-call this method manually in that scenario.

Unsupported / Custom Views

MonetCompat has a number of helper methods to get colors you are likely to want to use in your app:

getBackroundColor(Context) - Returns a color suitable for use as a Window background.

In light mode, this is the neutral 1 swatch, shade 50. In dark mode, it's neutral 1, shade 900. In the event that MonetCompat is not ready, the default background color (defaults to android.R.attr.windowBackground) is returned. Be warned that this may conflict with a splash screen, if you have set it to a bitmap (you may wish to override this color by setting MonetCompat.defaultBackgroundColor at runtime).

getBackgroundColorSecondary(Context) - Returns a color suitable for use as a Toolbar or similar element's background, or null.

In light mode, this is the neutral 1 swatch, shade 100. In dark mode, it's neutral 1, shade 600. In the event that MonetCompat is not ready, this method will return null as there is no Android attr for secondary window backgrounds (you should handle this yourself, perhaps fall back to the normal background color)

getAccentColor(Context) - Returns a color suitable for use as an accent color, for interactable elements or emphasis

In light mode, this is the accent 1 swatch, shade 700. In dark mode, it's accent 1, shade 100. In the event that MonetCompat is not ready, the default accent color (defaults to android.R.attr.colorAccent) is returned.

getPrimaryColor(Context) - Returns a color suitable as a primary color, for UI elements

In light mode, this is the accent 2 swatch, shade 100. In dark mode, it's accent 2, shade 100. In the event that MonetCompat is not ready, the default primary color (defaults to android.R.attr.colorPrimary) is returned.

getSecondaryColor(Context) - Returns a color suitable as a secondary color, for darker parts of UI elements

In light mode, this is the accent 2 swatch, shade 300. In dark mode, it's accent 2, shade 400. In the event that MonetCompat is not ready, the default secondary color (defaults to R.attr.colorPrimaryVariant) is returned.

Note: You can pass an override for the dark mode check into any of the above color methods, if you wish to get a color suitable for displaying in front of a permanently dark background, for example.

You can also access the full Monet swatches:

getMonetColors() - Returns a DynamicColorScheme, containing all the generated swatches.

You can then get a swatch from the neutral1, neutral2, accent1, accent2 or accent3 fields of DynamicColorScheme. Each swatch is a map of shades to color, with shades being 50, 100, 200, 300, 400, 500, 600, 700, 800, 900.

With these methods, you can use the colors as you wish within Views. If you are not using recreate mode, you may want to register your own listener for colors changing, to handle color changes without needing to call invalidate() from your fragment or activity.

addMonetColorsChangedListener(MonetColorsListener): Adds a listener for Monet colors changing

Pass notifySelf = true to automatically call the listener when it is attached

removeMonetColorsChangedListener(MonetColorsListener): Remove a listener

AlertDialog

MonetCompat supports theming AlertDialog using both the native AlertDialog and the material-dialogs library. Simply call applyMonet() on the AlertDialog or MaterialDialog to automatically apply Monet colors. If you have disabled recreate mode, these methods will also handle color changes for you.

Note: Due to a system limitation, AlertDialog cannot have more than one onDismissListener attached. As MonetCompat sets its own, you may pass a method to be called on dismiss in AlertDialog.applyMonet()

Clone this wiki locally