B3nedikt / restring

Restring is a android library to replace string resources dynamically
Apache License 2.0
319 stars 31 forks source link
android dynamic-strings kotlin language translations viewpump

Maven Central Build & Test codecov javadoc

Restring 6.0.0

An easy way to replace bundled Strings dynamically, or provide new translations for Android. Also supports plurals & string arrays.

1. Add dependencies

// Replace bundled strings dynamically
implementation 'dev.b3nedikt.restring:restring:6.0.0'

// Intercept view inflation
implementation 'dev.b3nedikt.viewpump:viewpump:4.0.13'

// Allows to update the text of views at runtime without recreating the activity
implementation 'dev.b3nedikt.reword:reword:4.0.4'

2. Initialize

Initialize Restring in your Application class:

Restring.init(this)

ViewPump.init(RewordInterceptor)

3. Inject into Context

If you use your application Context to retrieve string resources add the following to your Application class:

class SampleApplication : Application() {

    ...

    override fun getResources(): Resources {
        return Restring.wrapResources(applicationContext, super.getResources())
    }
}

If you have a BaseActivity you can add this there, otherwise you have to add it to all of your activities:

abstract class BaseActivity : AppCompatActivity() {

    private val appCompatDelegate: AppCompatDelegate by lazy {
        ViewPumpAppCompatDelegate(
                baseDelegate = super.getDelegate(),
                baseContext = this,
                wrapContext = Restring::wrapContext
        )
    }

    override fun getDelegate(): AppCompatDelegate {
        return appCompatDelegate
    }
}

4. Provide new Strings

Now load your strings like this:

Restring.putStrings(Locale.FRENCH, frenchStringsMap)

Now all strings in your app will be overriden by new strings provided to Restring.

Change Language of the app

Restring works with the current locale by default, however you can change your apps language like this:

Restring.locale = Locale.FRENCH

Restring will start using strings of the new locale.

Apply updated resources without restarting the app

After providing new strings or changing the app language you can either restart the app, or reload the UI like this:

// The layout containing the views you want to localize
val rootView = window.decorView.findViewById<ContentFrameLayout>(android.R.id.content)
Reword.reword(rootView)

If you have changed the texts of views in code, you need to update these texts manually of course, as this call will only update those string resources which you set in your xml layout files.

App Locale integration

This library was build for easy integration with my library AppLocale. AppLocale simplifies managing the Locales supported by your app.

To integrate it you need to first create a custom LocaleProvider:

object AppLocaleLocaleProvider : LocaleProvider {

    override val isInitial
        get() = AppLocale.isInitial

    override var currentLocale
        get() = AppLocale.desiredLocale
        set(value) {
            AppLocale.desiredLocale = value
        }
}

Then you can install this custom LocaleProvider when initializing Restring in your application class:

Restring.init(this)
Restring.localeProvider = AppLocaleLocaleProvider

If you already have some mechanism in your app to manage its Locales, you can easily integrate it with a custom LocaleProvider as well.

Custom Repository

By default, Restring will hold strings in memory for caching and persist them to the shared preferences after every write operation. You can however change this behavior by providing a custom implementation of the StringRepository interface to Restring like this:

Restring.stringRepository = newRepository

Restring comes with four StringRepository implementations for different use cases:

If these are not what you need you can also implement the StringRepository interface directly. The StringRepository interface is immutable, so you need to either:

Notes

For displaying a string, Restring tries to find it in the dynamic strings, and will use the bundled version as fallback. In other words, only the new provided strings will be overriden and for the rest the bundled version will be used. If you want you can also provide Restring with string resources which are not in your apps string.xmls. Restring will generate an id for these at runtime.

License

This is a fork of a library originally developed by Hamid Gharehdaghi. Also takes some inspiration from Philology by JcMinarro.

Copyright 2018-present Restring Contributors.

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.