Skip to content

mustafayigitt/Kala

Repository files navigation

Kala: Android Resource Management Library

mustafayigitt - kala

stars - kala forks - kala issues - kala

GitHub release License

Kala is an Android resource management library that allows you to easily manage your strings, drawables, and other resources. With Kala, you can centralize your resource management in one place, manage multiple language translations, and easily retrieve and manipulate resources from your application code.

Features

  • Centralized resource management
  • Support for multiple language translations
  • Outsource resource management
  • Retrieval of string and drawable resources with type-safety
  • Automatic caching for remote resource requests

Dependencies

Add the Jitpack source to project:

  ...
  repositories {
    maven { url 'https://jitpack.io' } 
  }

Add the following dependency to your build.gradle(module) file:

  dependencies {
    ...
    implementation 'com.github.mustafayigitt:kala:1.0.0'
  }

ResourceKey

ResourceKey class is a utility class that provides a type-safe and convenient way to access resources in an Android app. It is used to retrieve resources such as strings and drawables from the app's resource files.

ResourceKey is a generic class that takes a type parameter T which must be a non-null Any type. It also takes a key parameter of type String, which represents the name or identifier of the resource to retrieve.

class ResourceKey<T : Any>(
    private val type: KClass<T>,
    private val key: String
)

ResourceKey provides two operator functions to access resources. The first function is the invoke() function, which returns the resource object of type T. The second function is an overloaded invoke() function, which takes a variable number of arguments and returns the formatted string resource. These operators are powered by Kotlin Context-Receivers. The getString and getDrawable functions are accessed from the IResourceManager implemented in the ResourceManager.

    context(IResourceManager, Context)
    @Suppress("UNCHECKED_CAST")
    operator fun invoke(): T {
        return when (type) {
            String::class -> getString(key) as T
            Drawable::class -> getDrawable(this@Context, key) as T
            else -> throw IllegalArgumentException("Resource type is not supported")
        }
    }

    context(IResourceManager)
    operator fun invoke(vararg args: Any): String {
        return getString(key, *args)
    }

You should add this line to module kotlinOptions for Kotlin Context-Receivers:

    kotlinOptions {
        ...
        freeCompilerArgs = ["-Xcontext-receivers"]
    }

ResourceKey provides a companion object that has a reified invoke() function to create a new instance of the ResourceKey class with the specified type and key.

    companion object {
        inline operator fun <reified T : Any> invoke(key: String) = ResourceKey(T::class, key)
    }
    // Usage
    val HELLO = ResourceKey<String>("app.strings.hello")    

Usage

Define ResourceKeys

object ResourceKeys {

    // STRING KEYS
    val HELLO = ResourceKey<String>("app.strings.hello")
    val CHANGE_LANGUAGE = ResourceKey<String>("app.strings.change_language")
    val SUCCESS = ResourceKey<String>("app.strings.success")

    // OTHER KEYS
    val TEXT_FROM_OUTSOURCE = ResourceKey<String>("app.strings.text_from_outsource")

    // DRAWABLE KEYS
    val COUNTRY_FLAG = ResourceKey<Drawable>("flag")

}

Init

First, you need to initialize the ResourceManager singleton instance. The ResourceManager is responsible for managing all resources, caching remote resources, and serving resources to your application code.

  // Initialize the ResourceManager
  ResourceManager.setLanguage("en")
  ResourceManager.provideStrings(getEnglishStrings())
 ... 
private fun getEnglishStrings(): Map<String, String> {
        return mapOf(
            "${ResourceKeys.HELLO}" to "Hello!",
            "${ResourceKeys.CHANGE_LANGUAGE}" to "Change Language",
            "${ResourceKeys.SUCCESS}" to "Success!",
        )
    }

String Resources

To retrieve a string resource, use the ResourceKey class. You can define your own string resources in the ResourceKeys object.

  with(ResourceManager){ // Need to IResourceManager as context (Context-Receivers) 
    val helloString = ResourceKeys.HELLO() // Returns the string resource with key "app.strings.hello"
  }

You can also retrieve a formatted string resource:

  with(ResourceManager){ // Need to IResourceManager as context (Context-Receivers)
    val successString = ResourceKeys.SUCCESS("John Doe") // Returns "Success, John Doe!"
  }

Drawable Resources

To retrieve a drawable resource, use the ResourceKey class. You can define your own drawable resources in the ResourceKeys object.

  with(ResourceManager){ // Need to IResourceManager as context (Context-Receivers)
    val flagDrawable = ResourceKeys.COUNTRY_FLAG() // Returns the drawable resource with key "flag"
  }

Use without ResourceManager scope

  txtLabel.text = ResourceManager.getString("${ResourceKeys.HELLO}")

Outsource Resource Management (Remote/Local/Other)

Kala also supports outsourcing resource management. To use an outsourced resource provider, set the outsourceStringProvider property of the ResourceManager singleton instance.

  // Set the outsourced resource provider
  ResourceManager.outsourceStringProvider = ::getStringFromCache

  private fun getStringFromCache(lang: String, key: String): String? {
     return when (lang) {
         "en" -> when (key) {
             "${ResourceKeys.TEXT_FROM_OUTSOURCE}" -> "This text is from cache."
             else -> null
         }
         "tr" -> when (key) {
             "${ResourceKeys.TEXT_FROM_OUTSOURCE}" -> "Bu metin cache'ten alındı."
             else -> null
         }
         else -> null
     }
  } 

Clearing Cache

You can clear the resource cache by calling the clear function on the ResourceManager singleton instance.

  // Clear the resource cache
  ResourceManager.clear()

Contribution

We welcome all contributions to Kala! Please open issue when detect a problem. Every issue will be open to review and merge with pull requests.

License

Copyright 2023 @mustafayigitt

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.