An easy way to replace bundled Strings dynamically, or provide new translations for Android. Also supports plurals & string arrays.
// Replace bundled strings dynamically
implementation 'dev.b3nedikt.restring:restring:5.2.2'
// Intercept view inflation
implementation 'dev.b3nedikt.viewpump:viewpump:4.0.10'
// Allows to update the text of views at runtime without recreating the activity
implementation 'dev.b3nedikt.reword:reword:4.0.4'
Initialize Restring in your Application class:
Restring.init(this)
ViewPump.init(RewordInterceptor)
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 AppLocale.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
}
}
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.
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.
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.
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.
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:
-
MemoryStringRepository: Use this if you only want to keep strings in memory.
-
CachedStringRepository: Keeps all strings in memory & mirrors write operations to a PersistentStringRepository provided as a constructor parameter to it. All strings saved in the PersistentStringRepository are loaded lazily only when they are needed and cached in memory afterwards.
-
PersistentStringRepository: Simplifies implementing a repository which writes string resources to disk.
-
SharedPrefsStringRepository: Uses the PersistentStringRepository as a delegate to write string resources to androids SharedPreferences.
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:
-
Implement the MutableStringRepository, which will allow you to use the normal mutation methods of the Restring facade like Restring.putStrings(...).
-
Provide your own mutation methods in your implementation of the StringRepository interface.
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.
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.