Raffaele Rossi
Raffaele Rossi

Reputation: 3127

Delphi android strings file localization

I am doing a lot of Android apps using Delphi Seattle but the biggest problem for me is the localization. I have tried the DKLang package but I prefer avoiding 3rd party component. I need to be able to translate my application in english, italian and french.

Under android studio ide (it uses java and xml) I am able to add folders with a suffix that indicates the country:

res/
    values-en/
        strings.xml
    values-it/
        strings.xml
    values-fr/
        strings.xml

In Delphi I have used the Deployment manager to add the 3 folders above and I also have the strings.xml files. Each of them has the translations that I need.


I cannot understand how to load the values inside the strings.xml in a TLabel. Is there a particular class for this? Do I have to do it at runtime?

The strings.xml files are structured like this:

//values-en/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>    
    <string name="title">Congruences</string>       
</resources>

//values-it/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>    
    <string name="title">Congruenze</string>       
</resources>

Basically the name is an identifier and then the word inside the tag is the translation. I have seen that I can use this: // file xml , file type TAndroidHelper.GetResourceID('strings', 'string');

I have no idea on how I can load the information at runtime. Any idea?

Upvotes: 0

Views: 922

Answers (1)

zeus
zeus

Reputation: 13355

It's too much complicated to load the values inside the strings.xml (but it's possible), and it's not really the delphi way. In delphi what you can do instead is to use TLang

below the sample of the unit i use to translate

unit loki_Translation;

interface

uses system.classes,
     Fmx.controls,
     AlStringList,
     Win_definition;

function loki_translate(const AText: string): string;
function loki_SetLang(aLanguage: Twin_language): TALNVStringListU;

var
  vloki_CurrLang: TALNVStringListU;

implementation

uses FMX.Types,
     FMX.consts,
     system.SysUtils,
     alCommon,
     alString,
     WinDT_definition,
     loki_main;

{*****************************************************}
function loki_translate(const AText: string): string;
var idx: integer;
begin
  Idx := vloki_CurrLang.IndexOfName(AText);
  if Idx >= 0 then
    Result := vloki_CurrLang.ValueFromIndex[Idx]
  else
    Result := AText;
end;

{******************************************************************}
function loki_SetLang(aLanguage: Twin_language): TALNVStringListU;

  {$REGION 'ENU'}
  procedure _initENU;
  begin

    vloki_CurrLang.Add('_loki=loki');
    vloki_CurrLang.Add('_Exit_Application=Exit Application');
    vloki_CurrLang.Add('_AreYouSure=Are you sure?');
    vloki_CurrLang.Add('_Cancel=Cancel');
    vloki_CurrLang.Add('_OK=OK');
    vloki_CurrLang.Add('_Yes=Yes');
    vloki_CurrLang.Add('_speakx=Speak %s');
    vloki_CurrLang.Add('_and=and');

  end;
  {$ENDREGION}

{$IFDEF MSWINDOWS}
var i: integer;
{$ENDIF}

begin

  //init vloki_CurrLang
  ALfreeandnil(vloki_CurrLang);
  vloki_CurrLang := TALNVStringListU.Create;
  if aLanguage = ENU then _initENU;
  vloki_CurrLang.Duplicates := TDuplicates.Duperror;
  vloki_CurrLang.Sorted := True;
  result := vloki_CurrLang;

  //translate the TrayIconMenu
  {$IFDEF MSWINDOWS}
  for i := 0 to loki_mainForm.TrayIconMenu.ItemsCount - 1 do
    loki_mainForm.TrayIconMenu.Items[i].Text := loki_translate(loki_mainForm.TrayIconMenu.Items[i].TagString);
  {$ENDIF}

end;


{*****************************************}
procedure loki_TranslationInitialization;
begin
  vloki_CurrLang := TALNVStringListU.Create;
  CustomTranslateProc := loki_translate;
end;

{***************************************}
procedure loki_Translationfinalization;
begin
  ALfreeandnil(vloki_CurrLang);
end;

initialization
  Win_UpdateGlobalInitializationList(loki_TranslationInitialization, 65);
  Win_UpdateGlobalFinalizationList(loki_Translationfinalization, 65);

end.

and everywhere in your code when you need a string, you simply do

StrINeed := loki_translate('theStrName');

notice also as we do CustomTranslateProc := loki_translate; then it's could be compatible with label, but you must overload their loaded procedure (see alcinoe controls implementation, they did it)

i avoid Tlang because it's was very buggy for me, maybe this is not the case anymore in recent delphi version

Upvotes: 1

Related Questions