分享
 
 
 

Flex2 发现之旅:构建多语言本地化Flex应用

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

创建过Java多语言本地化应用的朋友应该都很熟悉Java的本地化资源访问的功能,现在好了,Flex2诸多激动人心更新中的一个就是本地化特性(localization feature),这倒是Adobe加强推广Flex2的一个强助力了(这一特性可以本地化Flex组件,这样估计以后会有中文版的Flex2了...),使用Flex2的本地化特性我们可以很容易创建多语言本地化的Flex应用,为我们的Flex应用打入国际市场添威助力,不过不像Java的本地化资源动态获取的方式,目前Flex2的本地化特性只支持静态的本地化资源嵌入,还不支持运行时动态获取本地化资源。

要本地化Flex2应用,我们需要将本地化资源文件编译为SWC库文件,然后在Flex应用中使用ActionScript或者MXML访问资源集(resource bundles )中的本地化值。

Flex2的本地化特性面向以以下人员:

Web应用开发人员

Web应用翻译人员

Flex框架开发人员

Flex框架翻译人员(中文版?!嘿嘿...)

本地化应用流程:

要本地化Flex代码,我们需要改变我们MXML和ActionScript代码,创建本地化属性文件和类,运行compc工具创建SWC库文件,最后使用mxmlc工具将我们的应用编译成SWF文件。

使用ResourceBundle API

要本地化Flex代码第一步是使用 mx.resource.ResourceBundle API替换期待本地化的硬编码内容。我们可以在ActionScript和MXML代码中使用ResourceBundle API。

ResourceBundle是ActionScript 3.0语言规范的一部分,其包含如下与本地化资源交互的方法:

static getBundle(name:String):ResourceBundle,这里name指的是属性文件名或ResourceBundle子类名。

getString(key:String):String, 这里key指的是属性文件或ResourceBundle子类中明值对名称

getObject(clsName:String):Object

使用本地化字符串

在下面的例子的ActionScript代码中,ResourceBundle API被用来设置某一按钮的label值,ResourceBundle.getBundle()方法获取某一资源集,然后使用 ResourceBundle.getString() 方法资源集中某一键值。

...

var myBundle:ResourceBundle = ResourceBundle.getBundle(getSystemManager(),

’MyBundle’);

myButton1.label = myBundle.getString(’myButton1_label’);

...

在MXML中,我们指定资源集名称和键名给@Resource指令来获取特点资源集中的特定值。如果,我们只标明键名,默认资源集名称为当前类名称。资源集名称为包含特定键的属性文件或ResourceBundle子类名称。@Resource有以下两种形式以下例子使用@Resource指令设置Button控件的label属性:

<mx:Button id="myButton1" label="@Resource(bundle=’MyButtonResources’,

key=’myButton1_label’)"

click="ti1.text=’myButton1.label=’+myButton1.label;"/>

在本地化字符串中使用绑定(Using binding with localized strings)

我们可以使用绑定表达式将@Resource指令的键参数绑定到相应属性文件的键值中,以下MXML代码使用绑定表达式作为@Resource指令的键参数: <mx:Label id=”lab” text="@Resource('lab.text', {product.name})"/>

以下示例是相应属性文件中键值对,{0}将会被product.name替代:

lab.text = We do not have {0} in stock.

我们也可以使用多个参数,例如在@Resource指令有多个参数时的:{0}和{1}。

如果需要的话,我们必须确保product.name是本地化的。

掉换本地化字符串顺序

我们可以基于区域使用某一本地化字符串或其他,例如,默认的英语属性文件可能包含如下键:

MYTEXT = {0} and {1}

而另外一个English属性文件可能包含如下值:

MYTEXT = {1} and {0}

某一MXML文件可能包含如下@Resource指令:

@Resource('MYTEXT', "My name is Bill.", "I am a developer.");

以上两个字符串在第二个区域中被掉换了。

以下是与以上@Resource指令等价的ActionScript代码:

var r:ResourceBundle;

r = ResourceBundle.getBundle(sm, "MyComponent1");

StringUtil.substitute(r.MYTEXT, "My name is Anant", "I am in the Flex team");

使用本地化对象和嵌入资源

在应用中,如果要使用ActionScript类或嵌入资源,如图像,我们可以调用ResourceBundle.getObject()方法,当我们获取一个ResourceBundle子类后,可以使用该ResourceBundle子类的getObject()方法从资源集中获取特定的类:

var bundle:ResourceBundle = ResourceBundle.getBundle(sm, "LocaleClasses");

var obj:Object = bundle.getObject("FormattingClass");

因为这里并没有到类的直接引用,我们必须使用ActionScript增加任意的可视子对象,例如:

var bundle:ResourceBundle = ResourceBundle.getBundle(sm, "LocaleClasses");

var obj:DisplayObject = DisplayObject(bundle.getObject("FormattingClass"));

myLocaleParent.add(obj);

以上示例中,LocaleClasses是某一我们创建的用来存放嵌入类的ResourceBundle子类, 该类引用了被ResourceBundle的getContent()方法返回的对象的类(这句有些拗口:This class references the classes that are needed in the ResourceBundle in an Object returned from its getContent() method. )。以下LocaleClasses示例:

public class LocaleClasses extends ResourceBundle {

public function LocaleClasses() {

super();

}

override protected static function getContent():Object {

var contentObj:Object = new Object();

contentObj.push("FormattingClass", FormattingClass);

contentObj.push("Class2", Class2);

// More classes can by added here.

return contentObj;

}

}

处理的过程类似嵌入资源,一共有三个步骤,首先我们必须使用基于类版本的嵌入,这就意味着我们必须为每个需要嵌入的资源创建一个类,例如,如果我们有一个JPG图片需要本地化,我们可以将以下RedJpg类添加到本地化目录中:

package {

import mx.core.SkinSprite;

[Embed(source=’red_jpg.jpg’)]

public class RedJpg extends SkinSprite {

}

}

第二步,将RedJpg类添加到某一扩展ResourceBundle的类中,这样是为了让编译器就有个需要处理的资源集了 。通常我们将所有需要的类放置在同一个资源集类中。

以下是一个包含RedJpg类的ResourceBundle子类:

package {

import mx.resource.ResourceBundle;

public class MyClassesBundle extends ResourceBundle {

public function MyClassesBundle()

{

super();

}

override protected static function getContent():Object {

var contentObj:Object = new Object();

content.push("RedJpg", RedJpg);

// add more class references here

return contentArr;

}

}

}

在我们创建包含资源集的SWC文件后,我们的第三步在ActionScript中使用ResourceBundle.getObject()方法获取该对象并且将其添加到我们应用需要的任意地方。以下是使用RedJpg对象的示例:

...

<mx:Image id="testJPG"/>

<mx:Script>

import mx.resource.ResourceBundle;

import mx.core.SkinSprite;

public function initialize () {

// We get the bundle here that is the name of the class in step 2.

ResourceBundle bundle = ResourceBundle.getBundle(sm,

"MyClassesBundle");

// here we specify the name of the class from step 1

SkinSprite sprite = SkinSprite(ResourceBundle.getObject("RedJpg"));

// and now we set up the Image

testJPG.source = sprite;

}

<mx:Script>

使用本地化属性文件和ResourceBundle子类

属性文件和目录结构

我们将存放需要本地化的字符串属性的属性文件放置在某一用户创建的本地目录中。

为了避免MXML @Resource指令的bundle参数,我们可以将属性文件名命名为与类的一样的名称。当然,标明资源集名称是个很好的练习。如果我们没有标明bundle参数,那么属性文件名必须与类名称一致,例如,/myApp/MyAlert.as的属性文件将为:/ fr_FR/myApp/MyAlert.properties,fr_FR为区域(locale )标识,类似的,我们可以在多个区域目录中包含多个属性文件,区域(locale )通过compc的locale选项设置,Locale不能在运行时使用Locale类修改。

locale目录必须为compc 的ActionScript类路径的一部分,但是不能为mxmlc编译主SWF文件时的ActiongScript类路径的一部分。

本地化属性文件与Java属性文件的格式一致,都是简单文本格式的名值对,例如:

Button1_label = Button1

Link1_label = Link1

CheckBox1_label = CheckBox1

RadioButton1_label = RadioButton1

RadioButton2_label = RadioButton2

RadioButton3_label = RadioButton3

PopUpButton1_label = PopUpButton1

属性文件中所有的文本必须为Latin-1 或者(和)Unicode-encoded (\udddd 符号)编码。

我们可以使用Java的native2ascii工具转换其他的格式,对于要处理大量的属性文件的情况,我们可以使用Ant的native2ascii任务批量转换属性文件为ASCII格式。

本地化文件和类搜索顺序

我们将本地化属性文件和ResourceBundle子类添加到相应的locale名称的目录下,更多本地化ActiongScript类信息,请查看“Using localized objects and embedded assets” 。

compc工具使用特定的locale法则搜索文件:精确locale名称、不带变种和国家的locale名称、最后是en_EN。

以下表格说明如果我们在使用compc命令编译本地化SWC文件时设置locale为fr_FR时的属性文件搜索顺序:

本地化文件 描述

/en_EN/Grape.as 未使用该文件,因为在fr_FR目录下有一个同名文件,该文件的优先级比更高

/en_EN/AppCommon.properties 该文件被使用,因为没有其他版本或者更高优先级的文件

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有