Dynamic color#

#

Dynamic color can create accessible UI color schemes based on content or user settings

https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color.png

Dynamic color experiences are built with M3 color schemes. Beginning with Android 12, users can generate individualized schemes through wallpaper selection and other customization settings. With M3 as a foundation, user-generated colors can coexist with app colors, putting a range of customizable visual experiences in the hands of users.

https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color-preview.png
  1. Baseline scheme

  2. Colors extracted from a wallpaper

  3. Colors extracted from content

Example of dynamic color from the list of standard color schemes#

from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import StringProperty, ColorProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.utils import hex_colormap

from kivymd.uix.menu import MDDropdownMenu
from kivymd.app import MDApp


KV = '''
<ColorCard>
    orientation: "vertical"

    MDLabel:
        text: root.text
        color: "grey"
        adaptive_height: True

    MDCard:
        theme_bg_color: "Custom"
        md_bg_color: root.bg_color


MDScreen:
    md_bg_color: app.theme_cls.backgroundColor

    MDIconButton:
        on_release: app.open_menu(self)
        pos_hint: {"top": .98}
        x: "12dp"
        icon: "menu"

    MDRecycleView:
        id: card_list
        viewclass: "ColorCard"
        bar_width: 0
        size_hint_y: None
        height: root.height - dp(68)

        RecycleGridLayout:
            cols: 3
            spacing: "16dp"
            padding: "16dp"
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
'''


class ColorCard(BoxLayout):
    text = StringProperty()
    bg_color = ColorProperty()


class Example(MDApp):
    menu: MDDropdownMenu = None

    def build(self):
        self.theme_cls.dynamic_color = True
        return Builder.load_string(KV)

    def get_instance_from_menu(self, name_item):
        index = 0
        rv = self.menu.ids.md_menu
        opts = rv.layout_manager.view_opts
        datas = rv.data[0]

        for data in rv.data:
            if data["text"] == name_item:
                index = rv.data.index(data)
                break

        instance = rv.view_adapter.get_view(
            index, datas, opts[index]["viewclass"]
        )

        return instance

    def open_menu(self, menu_button):
        menu_items = []
        for item, method in {
            "Set palette": lambda: self.set_palette(),
            "Switch theme style": lambda: self.theme_switch(),
        }.items():
            menu_items.append({"text": item, "on_release": method})
        self.menu = MDDropdownMenu(
            caller=menu_button,
            items=menu_items,
        )
        self.menu.open()

    def set_palette(self):
        instance_from_menu = self.get_instance_from_menu("Set palette")
        available_palettes = [
            name_color.capitalize() for name_color in hex_colormap.keys()
        ]

        menu_items = []
        for name_palette in available_palettes:
            menu_items.append(
                {
                    "text": name_palette,
                    "on_release": lambda x=name_palette: self.switch_palette(x),
                }
            )
        MDDropdownMenu(
            caller=instance_from_menu,
            items=menu_items,
        ).open()

    def switch_palette(self, selected_palette):
        self.theme_cls.primary_palette = selected_palette
        Clock.schedule_once(self.generate_cards, 0.5)

    def theme_switch(self) -> None:
        self.theme_cls.switch_theme()
        Clock.schedule_once(self.generate_cards, 0.5)

    def generate_cards(self, *args):
        self.root.ids.card_list.data = []
        for color in self.theme_cls.schemes_name_colors:
            value = f"{color}Color"
            self.root.ids.card_list.data.append(
                {
                    "bg_color": getattr(self.theme_cls, value),
                    "text": value,
                }
            )

    def on_start(self):
        Clock.schedule_once(self.generate_cards)


Example().run()
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color.gif

Example of a dynamic color from an image#

import os

from kivy.clock import Clock
from kivy.core.window import Window
from kivy.core.window.window_sdl2 import WindowSDL
from kivy.lang import Builder
from kivy.properties import StringProperty, ColorProperty

from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.app import MDApp


KV = '''
<ColorCard>
    orientation: "vertical"

    MDLabel:
        text: root.text
        color: "grey"
        adaptive_height: True

    MDCard:
        theme_bg_color: "Custom"
        md_bg_color: root.bg_color


MDScreen:
    md_bg_color: app.theme_cls.backgroundColor

    MDRecycleView:
        id: card_list
        viewclass: "ColorCard"
        bar_width: 0

        RecycleGridLayout:
            cols: 3
            spacing: "16dp"
            padding: "16dp"
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
'''


class ColorCard(MDBoxLayout):
    text = StringProperty()
    bg_color = ColorProperty()


class Example(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Window.bind(on_dropfile=self.on_drop_file)

    def on_drop_file(self, sdl: WindowSDL, path_to_file: str) -> None:
        ext = os.path.splitext(path_to_file)[1]
        if isinstance(path_to_file, bytes):
            path_to_file = path_to_file.decode()
        if isinstance(ext, bytes):
            ext = ext.decode()
        if ext in [".png", ".jpg"]:
            self.theme_cls.path_to_wallpaper = path_to_file
            Clock.schedule_once(self.generate_cards, 0.5)

    def build(self):
        self.theme_cls.dynamic_color = True
        self.theme_cls.theme_style = "Dark"
        return Builder.load_string(KV)

    def theme_switch(self) -> None:
        self.theme_cls.switch_theme()
        Clock.schedule_once(self.generate_cards, 0.5)

    def generate_cards(self, *args):
        self.root.ids.card_list.data = []
        for color in self.theme_cls.schemes_name_colors:
            value = f"{color}Color"
            self.root.ids.card_list.data.append(
                {
                    "bg_color": getattr(self.theme_cls, value),
                    "text": value,
                }
            )

    def on_start(self):
        Clock.schedule_once(self.generate_cards)


Example().run()
https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color-path-to_wallpapper.gif

API - kivymd.dynamic_color#

class kivymd.dynamic_color.DynamicColor#

Dynamic color class.

New in version 2.0.0.

primaryColor#

Primary color.

primaryColor is an ColorProperty and defaults to None.

primaryContainerColor#

Primary container color.

primaryContainerColor is an ColorProperty and defaults to None.

onPrimaryColor#

On primary color.

onPrimaryColor is an ColorProperty and defaults to None.

onPrimaryContainerColor#

On primary container color.

onPrimaryContainerColor is an ColorProperty and defaults to None.

secondaryColor#

Secondary color.

secondaryColor is an ColorProperty and defaults to None.

secondaryContainerColor#

Secondary container color.

secondaryContainerColor is an ColorProperty and defaults to None.

onSecondaryColor#

On secondary color.

onSecondaryColor is an ColorProperty and defaults to None.

onSecondaryContainerColor#

On secondary container color.

onSecondaryContainerColor is an ColorProperty and defaults to None.

tertiaryColor#

Tertiary color.

tertiaryColor is an ColorProperty and defaults to None.

tertiaryContainerColor#

Tertiary container color.

tertiaryContainerColor is an ColorProperty and defaults to None.

onTertiaryColor#

On tertiary color.

onTertiaryColor is an ColorProperty and defaults to None.

onTertiaryContainerColor#

On tertiary container color.

onTertiaryContainerColor is an ColorProperty and defaults to None.

surfaceColor#

Surface color.

surfaceColor is an ColorProperty and defaults to None.

surfaceDimColor#

Surface dim color.

surfaceDimColor is an ColorProperty and defaults to None.

surfaceBrightColor#

Surface bright color.

surfaceBrightColor is an ColorProperty and defaults to None.

surfaceContainerLowestColor#

Surface container lowest color.

surfaceContainerLowestColor is an ColorProperty and defaults to None.

surfaceContainerLowColor#

Surface container low color.

surfaceContainerLowColor is an ColorProperty and defaults to None.

surfaceContainerColor#

Surface container color.

surfaceContainerColor is an ColorProperty and defaults to None.

surfaceContainerHighColor#

Surface container high color.

surfaceContainerHighColor is an ColorProperty and defaults to None.

surfaceContainerHighestColor#

Surface container highest color.

surfaceContainerHighestColor is an ColorProperty and defaults to None.

surfaceVariantColor#

Surface variant color.

surfaceVariantColor is an ColorProperty and defaults to None.

surfaceTintColor#

Surface tint color.

surfaceTintColor is an ColorProperty and defaults to None.

onSurfaceColor#

On surface color.

onSurfaceColor is an ColorProperty and defaults to None.

onSurfaceLightColor#

On surface light color.

onSurfaceLightColor is an ColorProperty and defaults to None.

onSurfaceVariantColor#

On surface variant color.

onSurfaceVariantColor is an ColorProperty and defaults to None.

inverseSurfaceColor#

Inverse surface color.

inverseSurfaceColor is an ColorProperty and defaults to None.

inverseOnSurfaceColor#

Inverse on surface color.

inverseOnSurfaceColor is an ColorProperty and defaults to None.

inversePrimaryColor#

Inverse primary color.

inversePrimaryColor is an ColorProperty and defaults to None.

backgroundColor#

Background color.

backgroundColor is an ColorProperty and defaults to None.

onBackgroundColor#

On background color.

onBackgroundColor is an ColorProperty and defaults to None.

errorColor#

Error color.

errorColor is an ColorProperty and defaults to None.

errorContainerColor#

Error container color.

errorContainerColor is an ColorProperty and defaults to None.

onErrorColor#

On error color.

onErrorColor is an ColorProperty and defaults to None.

onErrorContainerColor#

On error container color.

onErrorContainerColor is an ColorProperty and defaults to None.

outlineColor#

Outline color.

outlineColor is an ColorProperty and defaults to None.

outlineVariantColor#

Outline variant color.

outlineVariantColor is an ColorProperty and defaults to None.

shadowColor#

Shadow color.

shadowColor is an ColorProperty and defaults to None.

scrimColor#

Scrim color.

scrimColor is an ColorProperty and defaults to None.

disabledTextColor#

Disabled text color.

disabledTextColor is an ColorProperty and defaults to None.

transparentColor#

Transparent color.

transparentColor is an ColorProperty and defaults to [0, 0, 0, 0].

rippleColor#

Ripple color.

rippleColor is an ColorProperty and defaults to ‘#BDBDBD’.