Set Android DatePicker title language - android

I have an app that is available in 4 languages, which can be chosen within the app. On Android, the DatePicker has a title. This title, even after setting the locale, always seems to favor the devices set locale. Only the title does this, as the functional part of the DatePicker is in the app-chosen language.
Here is what it looks like when the app is set to Korean.
How do I go about Changing that Thu, Aug 24 to Korean? I've set both Xamarin and Android locale to Korean. Is there an attribute in the Date Picker renderer I can set?
Thanks.

If you are doing something like this to apply a new locale context base configuration:
protected override void AttachBaseContext(Android.Content.Context #base)
{
Locale locale = Locale.Korean;
Locale.SetDefault(Locale.Category.Format, locale);
#base.Resources.Configuration.SetLocale(locale);
var newContext = #base.CreateConfigurationContext(#base.Resources.Configuration);
base.AttachBaseContext(newContext);
}
The Material-design CalendarView does not honor the context's locale correctly from the one that is passed to its .ctor and you end up with the wrong Title localization as shown in your question ;-(
One option is to subclass DatePicker and re-implement DatePickerCalendarDelegate and apply that to a sub-classed AlertDialog, but that is a bit crazy amount of coding to correctly address the issue.
So this is a fix (hack) that I have been using (simplified for SO, so you will need to API the various API level checks, etc..):
Material Design Fix (including Oreo beta):
// globals/cached
bool headerChangeFlag = true;
TextView headerTextView;
string headerDatePatternLocale;
SimpleDateFormat monthDayFormatLocale;
void SetHeaderMonthDay(DatePickerDialog dialog, Locale locale)
{
if (headerTextView == null)
{
// Material Design formatted CalendarView being used, need to do API level check and skip on older APIs
var id = base.Resources.GetIdentifier("date_picker_header_date", "id", "android");
headerTextView = dialog.DatePicker.FindViewById<TextView>(id);
headerDatePatternLocale = Android.Text.Format.DateFormat.GetBestDateTimePattern(locale, "EMMMd");
monthDayFormatLocale = new SimpleDateFormat(headerDatePatternLocale, locale);
headerTextView.SetTextColor(Android.Graphics.Color.Red);
headerTextView.TextChanged += (sender, e) =>
{
headerChangeFlag = !headerChangeFlag;
if (!headerChangeFlag)
return;
SetHeaderMonthDay(dialog, locale);
};
}
var selectedDateLocale = monthDayFormatLocale.Format(new Date((long)dialog.DatePicker.DateTime.ToUniversalTime().Subtract(
new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalMilliseconds));
headerTextView.Text = selectedDateLocale;
}
Usage:
var dialog = new DatePickerDialog(this);
dialog.Show();
SetHeaderMonthDay(dialog, Locale.Korean); // Call once, the text change event will update it when user changes date...
Results:

Related

Multilingual Not working For Date Picker Android

We have some issue with Date picker when change the locale of Android App. any one can help me out.
When we change the language of Device Francia(Canada) then app is working fine with this code
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Locale.setDefault(resources.configuration.locales.get(0))
}else{
Locale.setDefault(resources.configuration.locale)
}
but if we change the locale of app without change the device language from setting the getting incorrect result.
var locale=Locale(SharedPreferencesManager.getStringPreference(Constants.LOCALE, ""))
Locale.setDefault(locale)
val resources = resources
val configuration = resources.configuration
val displayMetrics = resources.displayMetrics
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configuration.setLocale(locale)
createConfigurationContext(configuration)
} else {
configuration.locale=locale
resources.updateConfiguration(configuration, displayMetrics)
}
Correct View
Incorrect View(Cancel and OK button not change as per app locale )
According to the http://code.google.com/p/android/issues/detail?id=25107 bug report on Android framework, the date picker is not using the String array of the shortened month of the Context of the app. Instead, it uses the System Locale.
You can use AppLocaleDatePickerDialog.java written by Gilbertwat.

How do I change the locale for the datepicker in Xamarin.Forms?

I have an Xamarin.Forms app that supports both English and French. How do I show the Calender (Month, Day of the Week text) for the DatePicker in French locale?
I've tried Xamarin.Forms
public void SetLocale(CultureInfo ci)
{
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
Console.WriteLine("CurrentCulture set: " + ci.Name);
}
I've tried changing the context before creating the datepicker dialog in my DatePicker custom renderer
var config = new Android.Content.Res.Configuration { Locale = Locale.CanadaFrench };
Context.Resources.UpdateConfiguration(config, Context.Resources.DisplayMetrics);
_dialog = new DatePickerDialog(Context, (o, e) =>
{
view.Date = e.Date;
((IElementController)view).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}, year, month, day);
I also tried this in my DatePicker custom renderer
protected override void
OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.DatePicker> e)
{
base.OnElementChanged(e);
this.Control.TextLocale = Locale.CanadaFrench;
}
None of these did anything to change the locale.
I also found this post that seems have done changing the calendar view to a different locale
Set Android DatePicker title language
But it wasn't clear how it was accomplished.
It turns out you have to add French as a language in the settings in order to show stuff in French.
Settings->General Management -> Language and Input->Language
And you just need these two lines in your DatePicker android Custom renderers to make the calendar French
this.Control.TextLocale = locale;
Resources.Configuration.SetLocale(locale);
If you title still remains in English, reference this post
Set Android DatePicker title language
Locale locale = new Locale("fr");
Control.TextLocale = locale;
Android.Content.Res.Configuration config = new Android.Content.Res.Configuration();
config.Locale = locale;
Locale.SetDefault(Locale.Category.Format, locale);
Resources.Configuration.SetLocale(locale);
Resources.Configuration.Locale = locale;

Issue when changing Locale to ARABIC in Android application

My Android application supports two languages: Arabic and English. Arabic is the default language.
Now, to make Arabic as default language, i am changing my app locale to Arabic in Splash Screen. And i have maintained both English and Arabic string files for the locale change. But, when i click on some other random fragments (eg. Navigation menu item), my app static strings changes back to English locale.
I assume this is because my app default locale might have been changed to English. This issue is generated randomly, no specific scenarios are noted.
Can you suggest any solution?
Edit: I am using Shared preferences to save the language.
First step you wand to save the language in your sqlite (ex: language saved in table settings at sqlite):
mDatabase = new SqliteItemDatabase(getApplicationContext());
final List<Setting> allsettings = mDatabase.listSettings();
String the_lang = "";
if(position == 0)
{
the_lang = "en";
}
else if(position == 1)
{
the_lang = "ar";
}
LocaleHelper.setLocale(LAngSelect.this, the_lang);// =>set language
mDatabase.updateSettings(new Setting(allsettings.get(0).getId(),the_lang));
mDatabase.close();
Second step: to set activity right-to-left you want to add in every activity:
mDatabase = new SqliteItemDatabase(this);
final List<Setting> allsettings = mDatabase.listSettings();
String langs = allsettings.get(0).getLang() ;
if(langs.equals("ar")) {
//HERE CHECK CONDITION FOR YOUR LANGUAGE if it is AR then
//change if it is english then don't
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
//Resources res = getResources(); //resource handle
}
}

Android. Espresso. How to check that text is shown in a specific language without hard code strings?

I need to check my fragment when I change the app language.
Here is my Android Espresso test:
#Test
public void changeLanguages() {
Resources resources = context.getResources();
String[] appLanguages = resources.getStringArray(R.array.app_lang_codes);
for (int index = 0; index < appLanguages.length; index++) {
String currentLang = appLanguages[index];
Locale currentLocale = new Locale(currentLang);
if (currentLocale.equals(AppLanguageService.getLocaleRO(context))) {
// click Romanian
onView(withId(R.id.containerLanguageRO)).perform(click());
onView(withId(R.id.textViewSelectLanguage)).check(matches(withText("Selecți limba")));
} else if (currentLocale.equals(AppLanguageService.getLocaleEN(context))) {
// click English
onView(withId(R.id.containerLanguageEN)).perform(click());
onView(withId(R.id.textViewSelectLanguage)).check(matches(withText("Select language")));
}
}
}
Ant it's working fine. OK!
But as you can see I need to hard code the string for a specific language for the test.
"Selecți limba" and "Select language". And I think it's not good.
Is it possible to not use hard code strings to check that text is shown in a specific language?
You can use
mActivityRule.getActivity()
to get the activity you are testing. With this you could fetch a string from your resources like this:
mActivityRule.getActivity().getResources().getString(R.string.your_string)
You could rewrite your check like this:
onView(withId(R.id.textViewSelectLanguage)).check(matches(withText(mActivityRule.getActivity().getResources().getString(R.string.your_string))));
where your_string is the name of your string resource in your strings.xml files.

Universal functions for showing date and time in any locale separately

I have a problem, I need the universal functions for showing date and time in any locale separately. But I can't find the way to do it without the checking the calendar.getLocale()
this function will give the date in US locale
static public String getDateFromCalendar(Calendar cal) {
return String.format("%tD", cal);
}
But if the Locale is russian I have to use istead this: String.format("%td.%tm.%tY", cal);
I don't want to use the conditional operations for every possible locale.
Please help to find the way to do is simplier.
Assuming you mean Java, I suggest you to consider the class java.text.DateFormat. Background is that every country/locale has its own typical date-time-format. For example:
public static String getDateFromCalendar(Calendar cal) {
// maybe get user-locale via ThreadLocal or via second method parameter
Locale locale = new Locale("ru", "Ru");
DateFormat dateFormat =
DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
return dateFormat.format(cal.getTime());
}
You can adjust the format style by choosing between SHORT, MEDIUM, LONG or FULL. For MEDIUM the output is: 05.04.2014 Compare that with the output for Locale.US yielding: Apr 5, 2014.

Categories

Resources