我使用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');
我不知道如何在运行时加载信息。有什么想法吗?
答案 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版本中不再是这种情况