Delphi android字符串文件本地化

时间:2017-04-19 17:33:49

标签: delphi firemonkey

我使用Delphi Seattle做了很多Android应用,但对我来说最大的问题是本地化。我尝试了DKLang包,但我更喜欢避免使用第三方组件。我需要能够用英语,意大利语和法语翻译我的应用程序。

在android studio ide下(它使用java和xml)我可以添加带有后缀的文件夹来指示国家:

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

在Delphi中,我使用部署管理器添加上面的3个文件夹,我也有strings.xml文件。他们每个人都有我需要的翻译。

我无法理解如何在TLabel中加载strings.xml中的值。这有特定的课程吗?我必须在运行时这样做吗?

strings.xml文件的结构如下:

//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>

基本上,名称是标识符,然后标记内的单词是翻译。我看到我可以使用这个:                               //文件xml,文件类型     TAndroidHelper.GetResourceID('strings','string');

我不知道如何在运行时加载信息。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

在strings.xml中加载值太复杂了(但它可能),而且它并不是真正的delphi方式。在德尔福,你可以做的是使用 TLang

在我用来翻译的单位样本下面

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.

当你需要一个字符串时代码中的任何地方,你只需要

StrINeed := loki_translate('theStrName');

还要注意我们的CustomTranslateProc:= loki_translate; 然后它可以与标签兼容,但你必须重载它们加载的程序(参见alcinoe控件实现,他们做了)

我避免使用Tlang,因为它对我来说非常麻烦,也许在最近的delphi版本中不再是这种情况