Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ContextThemeWrapperでthemeをより賢く

rmakiyama
April 27, 2020

 ContextThemeWrapperでthemeをより賢く

Android開発において欠かせないthemeをContextThemeWrapperを使ってさらに便利に使っていきましょうという発表です。

サンプルコードも書いてみたのでご興味があれば以下をご覧ください。
https://github.com/rmakiyama/android-theme-study

rmakiyama

April 27, 2020
Tweet

More Decks by rmakiyama

Other Decks in Programming

Transcript

  1. ContextThemeWrapperͰ

    themeΛΑΓݡ͘
    potatotips #69

    2020/04/27 rmakiyama

    View Slide

  2. ɹɹࣗݾ঺հ
    •຀ࢁྎ

    •Radiotalkגࣜձࣾ

    •AndroidΤϯδχΞ

    • @_rmakiyama

    • rmakiyama

    View Slide

  3. theme

    ×

    ContextThemeWrapper

    View Slide

  4. theme

    View Slide

  5. theme
    """




    android:theme="@style/AppTheme">




    android:label=“@string/app_name"

    android:theme=“@style/AppTheme.Hoge”>



    "

    View Slide

  6. theme
    """

    <br/><br/><item name="colorPrimary">@color/app_purple_500"</item><br/><br/><item name="colorPrimaryVariant">@color/app_purple_700"</item><br/><br/><item name="colorSecondary">@color/app_teal_500"</item><br/><br/><item name="colorSecondaryVariant">@color/app_teal_700"</item><br/><br/>"
    UIFNFBUUSJCVUFT

    View Slide

  7. theme attributes

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:background="?attr/colorPrimary"

    android:text="@string/button_save"

    android:textColor="?attr/colorOnPrimary" "/>

    View Slide

  8. theme attributes
    """

    <br/><br/><item name=“colorSecondary">@color/app_purple_500"</item><br/><br/>…<br/><br/>"

    """

    <br/><br/><item name=“colorSecondary">@color/app_purple_200"</item><br/><br/>…<br/><br/>"

    View Slide

  9. theme attributes
    """

    <br/><br/><item name=“colorSecondary">@color/app_purple_500"</item><br/><br/>…<br/><br/>"

    """

    <br/><br/><item name=“colorSecondary">@color/app_purple_200"</item><br/><br/>…<br/><br/>"

    View Slide

  10. theme attributes tips

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:background=“@color/app_purple_500“

    android:text="@string/button_save"

    android:textColor="@android:color/white" "/>

    View Slide

  11. theme attributes tips

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:background=“?attr/colorPrimary“

    android:text="@string/button_save"

    android:textColor=“?attr/colorOnPrimary” "/>

    View Slide

  12. ContextThemeWrapper

    View Slide

  13. ContextThemeWrapper
    java.lang.Object

    ↳ android.content.Context

    ↳ android.content.ContextWrapper

    ↳ android.view.ContextThemeWrapper

    ↳ android.app.Activity

    View Slide

  14. ContextThemeWrapperͱ͸
    l"DPOUFYUXSBQQFSUIBUBMMPXTZPV
    UPNPEJGZPSSFQMBDFUIFUIFNFPGUIFXSBQQFEDPOUFYUl
    SFGIUUQTEFWFMPQFSBOESPJEDPNSFGFSFODFBOESPJEWJFX$POUFYU5IFNF8SBQQFS

    View Slide

  15. ContextThemeWrapperͱ͸
    ςʔϚΛஔ͖׵͑ΒΕΔΑʂ

    View Slide

  16. ςʔϚΛஔ͖׵͑ͯΈΔ
    ϓϩεςʔλεʹͳͬͨΒ
    *NBHF7JFXͷ

    CBDLHSPVOEͷ৭Λม͑Δ

    View Slide

  17. ςʔϚΛஔ͖׵͑ͯΈΔ
    """

    <br/><br/><item name="colorPrimary">@color/app_purple_500"</item><br/><br/>…<br/><br/>"

    """




    android:background="?attr/colorPrimarySurface"



    app:srcCompat="@drawable/ic_launcher_foreground"

    … "/>

    View Slide

  18. ςʔϚΛஔ͖׵͑ͯΈΔ
    """

    <br/><br/><item name="colorPrimary">@color/app_purple_500"</item><br/><br/>…<br/><br/>"

    <br/><br/><item name="colorPrimary">@color/app_orange_500#</item><br/><br/>…<br/><br/>#

    View Slide

  19. ςʔϚΛஔ͖׵͑ͯΈΔ
    """

    class ProCaseFragment : DaggerFragment(R.layout.fragment_pro_case) {

    @Inject lateinit var status: UserStatusSetting

    override fun onCreateView(

    inflater: LayoutInflater,

    container: ViewGroup?,

    savedInstanceState: Bundle?

    ): View? {

    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    }

    }

    View Slide

  20. ςʔϚΛஔ͖׵͑ͯΈΔ
    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    View Slide

  21. ςʔϚΛஔ͖׵͑ͯΈΔ
    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    View Slide

  22. ςʔϚΛஔ͖׵͑ͯΈΔ
    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    View Slide

  23. ςʔϚΛஔ͖׵͑ͯΈΔ
    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    View Slide

  24. ςʔϚΛஔ͖׵͑ͯΈΔ
    """

    <br/><br/><item name="colorPrimary">@color/app_purple_500"</item><br/><br/>…<br/><br/>"

    <br/><br/><item name="colorPrimary">@color/app_orange_500"</item><br/><br/>…<br/><br/>"

    """




    android:background="?attr/colorPrimarySurface"



    app:srcCompat="@drawable/ic_launcher_foreground"

    … "/>

    View Slide

  25. ςʔϚΛஔ͖׵͑ͯΈΔ
    """

    class ProCaseFragment : DaggerFragment(R.layout.fragment_pro_case) {

    @Inject lateinit var status: UserStatusSetting

    override fun onCreateView(

    inflater: LayoutInflater,

    container: ViewGroup?,

    savedInstanceState: Bundle?

    ): View? {

    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    }

    }

    View Slide

  26. ςʔϚΛஔ͖׵͑ͯΈΔ
    """

    class ProCaseFragment : DaggerFragment(R.layout.fragment_pro_case) {

    @Inject lateinit var status: UserStatusSetting

    override fun onCreateView(

    inflater: LayoutInflater,

    container: ViewGroup?,

    savedInstanceState: Bundle?

    ): View? {

    val themedInflater: LayoutInflater = if (status.isProMode) {

    inflater.cloneInContext(

    ContextThemeWrapper(requireContext(), R.style.AppTheme_Pro)

    )

    } else inflater

    return super.onCreateView(themedInflater, container, savedInstanceState)

    }

    }

    View Slide

  27. ·ͱΊ
    • theme attributesΛ׆༻͠Α͏

    • ContextThemeWrapperΛ׆༻͠Α͏

    View Slide

  28. appendix
    • https:"//github.com/rmakiyama/android-theme-study

    • https:"//mixi-inc.github.io/AndroidTraining/introductions/1.04.basic-
    knowledge.html#context%E3%81%A8%E3%81%AF%EF%BC%9F

    • https:"//developer.android.com/reference/android/view/ContextThemeWrapper

    • https:"//developer.android.com/guide/topics/ui/themes

    • https:"//speakerdeck.com/nickbutcher/developing-themes-with-
    style-7d0571e3-6008-4ec5-99c6-aa5669520124

    View Slide