3

I'm new at Android and Kotlin. I'm trying to create a ResourcesHelper class to easily access my custom colors and fonts from any other custom class in my app. But in this helper I don't have any context. I've read ways to get the context extending the Application class but then compiler says I can't access this context in my ResourcesHelper companion object as it would create memory leaks. Also I ended up with optional chained.

Here is how I would like to be able to use it :

class ResourcesHelper {

    companion object {
        val lightBlue = resources.getColor(R.color.lightBlue)
        val customBlue = resources.getColor(R.color.customBlue)
        // [...]    
        val fontAwesome = resources.getFont(R.font.fontawesome)
        val lemonMilk = resources.getFont(R.font.lemonmilk)
    }
}

enum class ButtonStyle {
    MENU,
    // [...]
    VICTORY
}

class CustomButton(c: Context, attrs: AttributeSet) : Button(c, attrs) {

    var isButtonActivated = false

    fun setStyle(style: ButtonStyle) {
        setBackgroundColor(ResourcesHelper.transparent)

        when(style) {
            ButtonStyle.MENU -> {
                setText(R.string.menu_button)
                typeface = ResourcesHelper.lemonMilk
                setBackgroundColor(ResourcesHelper.customRed)
                setTextColor(ResourcesHelper.white)
            }
            // [...]
            ButtonStyle.VICTORY -> {
                setText(R.string.victory_button)
                typeface = ResourcesHelper.lemonMilk
                setBackgroundColor(ResourcesHelper.customRed)
                setTextColor(ResourcesHelper.white)
            }
        }
    }
}

I also read this post Android access to resources outside of activity but it's in Java and I have no idea on how to do it in Kotlin.

I am completely lost on what and how to do this... Or if there is a better way to achieve reaching resources from anywhere.

Thanks for your help

C. Moulinet
  • 202
  • 3
  • 13
  • *compiler says I can't access this context in my ResourcesHelper companion object as it would create memory leaks* - I think it's a warning, not an error. Also you can ignore it. The application context cannot be leaked – Tim Jan 21 '19 at 10:57
  • Thanks ! So I get an optional context. Is it safe do `val myCustomColor = context!!.getColor(R.color.lightBlue)` ? Can my applicationContext be null ? – C. Moulinet Jan 21 '19 at 11:08
  • I don't know what you mean. The context you retrieve with your application class is not nullable – Tim Jan 21 '19 at 11:14
  • 1
    I tried to copy something like this https://stackoverflow.com/questions/9445661/how-to-get-the-context-from-anywhere and Android studio converted it in Kotlin and made the context nullable. But I simply can do `val context = Application().applicationContext` directly in my ResourcesHelper this way I have a non nullable context. – C. Moulinet Jan 21 '19 at 11:28
  • Although if I do like so it crashes the app with a `Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109) at com...Common.ResourcesHelper.(ResourcesHelper.kt:10)` – C. Moulinet Jan 21 '19 at 11:37

2 Answers2

4

For Color, String, etc system resources you can use the Resources class, as shown below

import android.content.res.Resources

    class ResourcesHelper {
    
        companion object {
            val lightBlue = Resources.getSystem().getColor(R.color.lightBlue)
    
        }
    
    }
BrentHarsh
  • 33
  • 5
Sachin Kasaraddi
  • 597
  • 5
  • 12
2

If you want to support different Android versions I'll recommend to use ContextCompat. It provides unified interface to access different resources and backward compatibility for older Android versions.

For AnroidX use androidx.core.content.ContextCompat, for SupportV4: android.support.v4.content.ContextCompat.

val lightBlue = ContextCompat.getColor(context, R.color.lightBlue)
val customBlue = ContextCompat.getColor(context, R.color.customBlue)
amatkivskiy
  • 1,154
  • 8
  • 11