Skip to content

Commit

Permalink
Fix the language selector for newer Androids
Browse files Browse the repository at this point in the history
  • Loading branch information
gzsombor committed Aug 28, 2024
1 parent f0283ea commit abe85cf
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,17 @@

import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.os.LocaleListCompat;
import androidx.core.util.Pair;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;

import com.google.common.base.Joiner;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -74,41 +73,51 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
configureLanguageSelector();
}

private List<String> getLanguages() {
List<String> result = new ArrayList<>();
try {
XmlResourceParser xpp = getResources().getXml(R.xml._generated_res_locale_config);
while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
if (xpp.getEventType() == XmlPullParser.START_TAG) {
if ("locale".equals(xpp.getName()) && xpp.getAttributeCount() > 0 && "name".equals(xpp.getAttributeName(0))) {
result.add(xpp.getAttributeValue(0));
}
}
xpp.next();
}
Logger.i(this, "Language list:"+result);
} catch(XmlPullParserException|IOException e) {
Logger.e(this, "Unable to parse locale config: "+e.getMessage(), e);
}
return result;
}

private void configureLanguageSelector() {
ListPreference languageSelector = findPreference(getString(R.string.pref_key_app_language));

List<String> languages = getLanguages();
LocaleListCompat localeList = LocaleListCompat.forLanguageTags(Joiner.on(",").join(languages));
int size = localeList.size();
String[] localeCodes = new String[size];
String[] localeNames = new String[size];
for (int i = 0;i<size;i++) {
Locale locale = localeList.get(i);
localeNames[i] = locale.getDisplayName();
localeCodes[i] = locale.getLanguage();
}
languageSelector.setEntries(localeNames);
languageSelector.setEntryValues(localeCodes);
}
private List<String> getLanguages() {
List<String> result = new ArrayList<>();
try {
XmlResourceParser xpp = getResources().getXml(R.xml._generated_res_locale_config);
while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
if (xpp.getEventType() == XmlPullParser.START_TAG) {
if ("locale".equals(xpp.getName()) && xpp.getAttributeCount() > 0 && "name".equals(xpp.getAttributeName(0))) {
result.add(xpp.getAttributeValue(0));
}
}
xpp.next();
}
Logger.i(this, "Language list:"+result);
} catch(XmlPullParserException|IOException e) {
Logger.e(this, "Unable to parse locale config: "+e.getMessage(), e);
}
return result;
}

private static Comparator<Pair<String, String>> ENGLISH_COMPARATOR = Comparator.comparing(pair -> "en".equals(pair.first) ? 0 : 1);
private static Comparator<Pair<String, String>> COMPARATOR = ENGLISH_COMPARATOR.thenComparing(pair -> pair.second);

private void configureLanguageSelector() {
ListPreference languageSelector = findPreference(getString(R.string.pref_key_app_language));

List<String> languages = getLanguages();
LocaleListCompat localeListCompat = AppCompatDelegate.getApplicationLocales();
Locale defaultLocale = localeListCompat.isEmpty() ? Locale.getDefault() : localeListCompat.get(0);
Logger.i(this, "Default locale: " + defaultLocale + " -> language:" + defaultLocale.getLanguage());
List<Pair<String, String>> languageWithCodes = languages.stream()
.map(code -> Pair.create(code, new Locale(code).getDisplayLanguage(defaultLocale)))
.sorted(COMPARATOR)
.collect(Collectors.toList());
int size = languageWithCodes.size();
String[] localeCodes = new String[size];
String[] localeNames = new String[size];
for (int i = 0;i<size;i++) {
Pair<String, String> locale = languageWithCodes.get(i);
localeNames[i] = locale.second;
localeCodes[i] = locale.first;
}
languageSelector.setEntries(localeNames);
languageSelector.setEntryValues(localeCodes);
languageSelector.setValue(defaultLocale.getLanguage());
}

private void configureCountrySelector() {
ListPreference countrySelector = findPreference(getString(R.string.pref_key_default_content_country));
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@

<string name="pref_key_app_language" translatable="false">pref_key_app_language</string>
<string name="pref_title_app_language">Application Language</string>
<string name="pref_summary_app_language">The language used for all the labels in the application</string>
<string name="pref_summary_app_language">The language used for all the labels in the application: %s</string>

<!--
SPONSORBLOCK
Expand Down

0 comments on commit abe85cf

Please sign in to comment.