/restring

Replace bundled Strings dynamically, or provide new translations, for Android

Primary LanguageKotlin

Download Build Status codecov

Restring 3.1.0

An easy way to replace bundled Strings dynamically, or provide new translations for Android.

1. Add dependency

implementation 'com.b3nedikt.restring:restring:3.1.0'
implementation 'io.github.inflationx:viewpump:2.0.3'

2. Initialize

Initialize Restring in your Application class:

Restring.init(this,
        new RestringConfig.Builder()
                .stringsLoader(new SampleStringsLoader())
                .loadAsync(false) // If string loader should load strings asynchronously, default true
                .build()
        );

ViewPump.init(ViewPump.builder()
        .addInterceptor(RestringInterceptor.INSTANCE)
        .build()
        );

3. Inject into Context

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

 @Override
 protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(ViewPumpContextWrapper.wrap(Restring.wrapContext(newBase)));
}

@Override
public Resources getResources() {
    return getBaseContext().getResources();
}

4. Provide new Strings

There're two ways to provide new Strings. You can use either way or both.

First way: You can implement Restring.StringsLoader like this:

public class SampleStringsLoader implements Restring.StringsLoader {

    @NotNull
    @Override
    public List<Locale> getLocales() {
        return Arrays.asList(Locale.ENGLISH, Locale.US);
    }

    @NotNull
    @Override
    public Map<String, CharSequence> getStrings(@NotNull Locale locale) {
        final Map<String, CharSequence> map = new HashMap<>();
        // Load strings here...
        return map;
    }
}

and initialize Restring like this:

Restring.init(context,
              new RestringConfig.Builder()
                  .stringsLoader(new MyStringsLoader())
                  .build()
        );

Second way: Load your Strings in any way / any time / any place and just call this:

// e.g. locale=Locale.EN newStrings=map of (key-value)s
Restring.setStrings(locale, newStrings);

5. Done!

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.setLocale(Locales.FRENCH);

// The layout containing the views you want to localize
final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
Restring.reword(rootView);

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
final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
Restring.reword(rootView);

Custom Repository

By default, Restring will hold strings in memory for caching and persisting them to shared preferences after loading. You can however change the repository for saving the strings, to e.g. only keep them in memory like this:

Restring.init(this,
        new RestringConfig.Builder()
                .stringsLoader(new SampleStringsLoader())
                .stringRepository(new MemoryStringRepository())
                .build()
);

If needed you can also provide custom repositories if you want to e.g. save the strings in a database instead of the SharedPreferences, or if you don´t want to use the StringsLoader mechanism.

Plurals & String arrays

Restring also supports quantity strings (plurals) and string arrays. Just provide them in the strings loader like this or return an empty map if you don´t need plurals or string arrays. In kotlin these two methods already have a default implementation returning an empty map.

public class SampleStringsLoader implements Restring.StringsLoader {

    ...

    @NotNull
    @Override
    public Map<String, Map<PluralKeyword, CharSequence>> getQuantityStrings(@NotNull Locale locale) {
        // Load quantity strings (plurals) here
        return map;
    }

    @NotNull
    @Override
    public Map<String, CharSequence[]> getStringArrays(@NotNull Locale locale) {
        // Load string arrays here
        return map;
    }
}

Notes

For displaying a string, Restring tries to find it in dynamic strings, and will use bundled version as fallback. In the other words, Only the new provided strings will be overriden and for the rest the bundled version will be used.

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.