$30 off During Our Annual Pro Sale. View Details »

Vasya Drobushkov: Android Dark Theme

Vasya Drobushkov: Android Dark Theme

How to support dark theme in your Android app

Vasya

July 19, 2019
Tweet

More Decks by Vasya

Other Decks in Programming

Transcript

  1. Dark Theme

    View Slide

  2. Vasya Drobushkov
    Android Developer @ Ciklum
    Github: @krossovochkin
    Medium: @krossovochkin

    View Slide

  3. Android Oreo Wallpapers

    View Slide

  4. Android Pie Display Settings

    View Slide

  5. Android Pie Display Settings

    View Slide

  6. Android Pie Display Settings

    View Slide

  7. Android Pie Display Settings

    View Slide

  8. Android Pie Night mode

    View Slide

  9. Android Pie Night mode

    View Slide

  10. Android Pie Night mode

    View Slide

  11. Android Pie Night mode

    View Slide

  12. Android Q Display Settings

    View Slide

  13. Android Q Display Settings

    View Slide

  14. Android Q Display Settings

    View Slide

  15. Why?
    Environment Battery Accessibility

    View Slide

  16. View Slide

  17. Force Dark
    <br/><item name="android:forceDarkAllowed">true</item><br/>

    View Slide

  18. Force Dark Result
    Q+

    View Slide

  19. DayNight Theme
    parent="Theme.AppCompat.DayNight" />
    // OR
    parent="Theme.MaterialComponents.DayNight" />

    View Slide

  20. DayNight First Try

    View Slide

  21. -night resources
    // values/themes.xml
    name="Theme.AppCompat.DayNight" parent="Theme.AppCompat.Light"/>
    // values-night/themes.xml
    name="Theme.AppCompat.DayNight" parent="Theme.AppCompat"/>

    View Slide

  22. Custom Night Resources
    // values-night/colors.xml

    #511b43
    #511b43
    #ff6868

    View Slide

  23. Default Updated

    View Slide

  24. Force Dark Custom DayNight
    Background darker

    View Slide

  25. Force Dark Custom DayNight
    Dividers are dark

    View Slide

  26. Force Dark Custom DayNight
    Button style

    View Slide

  27. Android P

    View Slide

  28. Dynamic DayNight mode
    AppCompatDelegate.setDefaultNightMode(mode)
    getDelegate().setLocalNightMode(mode)
    System
    Application
    Activity

    View Slide

  29. Night Modes
    ● MODE_NIGHT_NO // LIGHT
    ● MODE_NIGHT_YES // DARK
    ● MODE_NIGHT_AUTO_BATTERY // DARK IN BATTERY SAVE MODE
    ● MODE_NIGHT_FOLLOW_SYSTEM // SYSTEM PREFERENCE

    View Slide

  30. Application Settings
    setPreferencesFromResource(R.xml.preferences, rootKey)
    themePreference?.onPreferenceChangeListener =
    Preference.OnPreferenceChangeListener { _, mode ->
    AppCompatDelegate.setDefaultNightMode(mode)
    true
    }

    View Slide

  31. Application Settings (Q)

    View Slide

  32. Application Settings (prior to Q)

    View Slide

  33. Issue

    View Slide

  34. Persistence
    class App : Application() {
    override fun onCreate() {
    super.onCreate()
    val mode = PreferenceManager
    .getDefaultSharedPreferences(this)
    .getInt("theme_key", MODE_NIGHT_NO)
    AppCompatDelegate.setDefaultNightMode(mode)

    View Slide

  35. Fixed

    View Slide

  36. Sum up
    ● Extend DayNight Theme
    ● Provide additional -night resources for Dark Theme
    ● Add preference for changing mode inside Application
    ● Persist preference choice
    ● Work with designer for the rest

    View Slide

  37. Test Dark Theme

    View Slide

  38. Test force dark

    View Slide

  39. Disable force dark for particular views
    android:forceDarkAllowed="false"
    tools:targetApi="q"/>
    view.setForceDarkAllowed(false)

    View Slide

  40. Attributes
    android:textColor="?android:attr/textColorPrimary"

    />

    View Slide

  41. Check is Dark theme applied
    fun Context.isDarkTheme(): Boolean {
    val mode = this.resources.configuration.uiMode and
    Configuration.UI_MODE_NIGHT_MASK
    return mode == Configuration.UI_MODE_NIGHT_YES
    }

    View Slide

  42. AppCompat Material Components

    View Slide

  43. AppCompat Material Components

    View Slide

  44. Elevation
    val bg = MaterialShapeDrawable
    .createWithElevationOverlay(this, 32.0f)
    // OR
    val color = ElevationOverlayProvider(this)
    .getSurfaceColorWithOverlayIfNeeded(32.0f)

    View Slide

  45. https://github.com/krossovochkin/DarkThemeSample
    Sample project

    View Slide

  46. Questions?

    View Slide