1# UI国际化 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @camlostshi--> 5<!--Designer: @lanshouren--> 6<!--Tester: @liuli0427--> 7<!--Adviser: @HelloCrease--> 8 9本文介绍如何实现应用程序UI界面的国际化,包含资源配置和镜像布局,关于应用适配国际化的详细参考,请参考[Localization Kit(本地化开发服务)](../internationalization/i18n-l10n.md)。 10 11## 利用资源限定词配置国际化资源 12 13在开发阶段,通过DevEco Studio,可以为应用在对应语言和地区的资源限定词目录下配置不同的资源,来实现UI国际化。详细介绍请参考[资源分类与访问](../quick-start/resource-categories-and-access.md)。 14 15## 使用镜像能力 16 17不同国家对文本对齐方式和读取顺序有所不同,例如英语采用从左到右的顺序,阿拉伯语和希腊语则采用从右到左(RTL)的顺序。为满足不同用户的阅读习惯,ArkUI提供了镜像能力。在特定情况下将显示内容在X轴上进行镜像反转,由从左向右显示变成从右向左显示。 18 19| 镜像前 | 镜像后 | 20| ----------- | ----------------------------------- | 21||| 22 23当组件满足以下任意条件时,镜像能力生效: 24 251. 组件的direction属性设置为Direction.Rtl。 26 272. 组件的direction属性设置为Direction.Auto,且当前的系统语言(如维吾尔语)的阅读习惯是从右向左。 28 29### 基本概念 30 31- LTR:顺序为从左向右。 32- RTL:顺序为从右向左。 33 34### 使用约束 35 36ArkUI 如下能力已默认适配镜像: 37 38| 类别 | 名称 | 39| -------- | ------------------------------------------------------------ | 40| 基础组件 | [Swiper](../reference/apis-arkui/arkui-ts/ts-container-swiper.md)、[Tabs](../reference/apis-arkui/arkui-ts/ts-container-tabs.md)、[TabContent](../reference/apis-arkui/arkui-ts/ts-container-tabcontent.md)、[List](../reference/apis-arkui/arkui-ts/ts-container-list.md)、[Progress](../reference/apis-arkui/arkui-ts/ts-basic-components-progress.md)、[CalendarPicker](../reference/apis-arkui/arkui-ts/ts-basic-components-calendarpicker.md)、[CalendarPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md)、[TextPicker](../reference/apis-arkui/arkui-ts/ts-basic-components-textpicker.md)、[TextPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-textpicker-dialog.md)、[DatePicker](../reference/apis-arkui/arkui-ts/ts-basic-components-datepicker.md)、[DatePickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-datepicker-dialog.md)、[Grid](../reference/apis-arkui/arkui-ts/ts-container-grid.md)、[WaterFlow](../reference/apis-arkui/arkui-ts/ts-container-waterflow.md)、[Scroll](../reference/apis-arkui/arkui-ts/ts-container-scroll.md)、[ScrollBar](../reference/apis-arkui/arkui-ts/ts-basic-components-scrollbar.md)、[AlphabetIndexer](../reference/apis-arkui/arkui-ts/ts-container-alphabet-indexer.md)、[Stepper](../reference/apis-arkui/arkui-ts/ts-basic-components-stepper.md)、[SideBarContainer](../reference/apis-arkui/arkui-ts/ts-container-sidebarcontainer.md)、[Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md)、[NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md)、[Rating](../reference/apis-arkui/arkui-ts/ts-basic-components-rating.md)、[Slider](../reference/apis-arkui/arkui-ts/ts-basic-components-slider.md)、[Toggle](../reference/apis-arkui/arkui-ts/ts-basic-components-toggle.md)、[Badge](../reference/apis-arkui/arkui-ts/ts-container-badge.md)、[Counter](../reference/apis-arkui/arkui-ts/ts-container-counter.md)、[Chip](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Chip.md)、[SegmentButton](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SegmentButton.md)、[bindMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindmenu)、[bindContextMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindcontextmenu8)、[TextInput](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md)、[TextArea](../reference/apis-arkui/arkui-ts/ts-basic-components-textarea.md)、[Search](../reference/apis-arkui/arkui-ts/ts-basic-components-search.md)、[Stack](../reference/apis-arkui/arkui-ts/ts-container-stack.md)、[GridRow](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md)、[Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md)、[Select](../reference/apis-arkui/arkui-ts/ts-basic-components-select.md)、[Marquee](../reference/apis-arkui/arkui-ts/ts-basic-components-marquee.md)、[Row](../reference/apis-arkui/arkui-ts/ts-container-row.md)、[Column](../reference/apis-arkui/arkui-ts/ts-container-column.md)、[Flex](../reference/apis-arkui/arkui-ts/ts-container-flex.md)、[RelativeContainer](../reference/apis-arkui/arkui-ts/ts-container-relativecontainer.md)、[ListItemGroup](../reference/apis-arkui/arkui-ts/ts-container-listitemgroup.md) | 41| 高级组件 | [SelectionMenu](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SelectionMenu.md) 、[TreeView](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-TreeView.md) 、[Filter](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Filter.md)、[SplitLayout](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SplitLayout.md)、[ToolBar](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ToolBar.md)、[ComposeListItem](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ComposeListItem.md)、[EditableTitleBar](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-EditableTitleBar.md)、[ProgressButton](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ProgressButton.md)、[SubHeader](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SubHeader.md) 、[Popup](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Popup.md)、[Dialog](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Dialog.md)、[SwipeRefresher](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-SwipeRefresher.md) | 42| 通用属性 | [position](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#position)、[markAnchor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#markanchor)、[offset](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#offset)、[alignRules](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#alignrules12)、[borderWidth](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderwidth)、[borderColor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#bordercolor)、[borderRadius](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderradius)、[padding](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#padding)、[margin](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#margin) | 43| 接口 | [AlertDialog](../reference/apis-arkui/arkui-ts/ts-methods-alert-dialog-box.md)、[ActionSheet](../reference/apis-arkui/arkui-ts/ts-methods-action-sheet.md)、[promptAction.showDialog](../reference/apis-arkui/js-apis-promptAction.md#promptactionshowdialogdeprecated)、[promptAction.showToast](../reference/apis-arkui/js-apis-promptAction.md#promptactionshowtoastdeprecated) | 44 45但如下三种场景还需要进行适配: 46 471. 界面布局、边框设置:关于方向类的通用属性,如果需要支持镜像能力,使用泛化的方向指示词 start/end入参类型替换 left/right、x/y等绝对方向指示词的入参类型,来表示自适应镜像能力。 48 492. Canvas组件只有限支持文本绘制的镜像能力。 50 513. XComponent组件不支持组件镜像能力。 52 53### 界面布局和边框设置 54 55目前,以下三类通用属性需要使用新入参类型适配: 56 57位置设置:[position](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#position)、[markAnchor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#markanchor)、[offset](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#offset)、[alignRules](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#alignrules12) 58 59边框设置:[borderWidth](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderwidth)、[borderColor](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#bordercolor)、[borderRadius](../reference/apis-arkui/arkui-ts/ts-universal-attributes-border.md#borderradius) 60 61尺寸设置:[padding](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#padding)、[margin](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md#margin) 62 63以position为例,需要把绝对方向x、y描述改为新入参类型start、end的描述,其他属性类似。 64 65```typeScript 66import { LengthMetrics } from '@kit.ArkUI'; 67 68@Entry 69@Component 70struct Index1 { 71 build() { 72 Stack({ alignContent: Alignment.TopStart }) { 73 Stack({ alignContent: Alignment.TopStart }) { 74 Column() 75 .width(100) 76 .height(100) 77 .backgroundColor(Color.Red) 78 .position({ start: LengthMetrics.px(200), top: LengthMetrics.px(200) }) //需要同时支持LTR和RTL时使用API12新增的LocalizedEdges入参类型, 79 //仅支持LTR时等同于.position({ x: '200px', y: '200px' }) 80 81 }.backgroundColor(Color.Blue) 82 }.width("100%").height("100%").border({ color: '#880606' }) 83 } 84} 85``` 86 87### 自定义绘制Canvas组件 88 89Canvas组件的绘制内容和坐标均不支持镜像能力。已绘制到Canvas组件上的内容并不会跟随系统语言的切换自动做镜像效果。 90 91[CanvasRenderingContext2D](../reference/apis-arkui/arkui-ts/ts-canvasrenderingcontext2d.md)的文本绘制支持镜像能力,在使用时需要与Canvas组件的通用属性direction(组件显示方向)和CanvasRenderingContext2D的属性direction(文本绘制方向)协同使用。具体规格如下: 92 931. 优先级:CanvasRenderingContext2D的direction属性 > Canvas组件通用属性direction > 系统语言决定的水平显示方向。 942. Canvas组件本身不会自动跟随系统语言切换镜像效果,需要应用监听到系统语言切换后自行重新绘制。 953. CanvasRenderingContext2D绘制文本时,只有符号等文本会对绘制方向生效,英文字母和数字不响应绘制方向的变化。 96 97```typeScript 98import { BusinessError, commonEventManager } from '@kit.BasicServicesKit'; 99 100@Entry 101@Component 102struct Index { 103 @State message: string = 'Hello world'; 104 private settings: RenderingContextSettings = new RenderingContextSettings(true) 105 private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) 106 107 aboutToAppear(): void { 108 // 监听系统语言切换 109 let subscriber: commonEventManager.CommonEventSubscriber | null = null; 110 let subscribeInfo2: commonEventManager.CommonEventSubscribeInfo = { 111 events: ["usual.event.LOCALE_CHANGED"], 112 } 113 commonEventManager.createSubscriber(subscribeInfo2, (err: BusinessError, data: commonEventManager.CommonEventSubscriber) => { 114 if (err) { 115 console.error(`Failed to create subscriber. Code is ${err.code}, message is ${err.message}`); 116 return; 117 } 118 119 subscriber = data; 120 if (subscriber !== null) { 121 commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => { 122 if (err) { 123 console.error(`订阅语言地区状态变化公共事件失败. Code is ${err.code}, message is ${err.message}`); 124 return; 125 } 126 console.info('成功订阅语言地区状态变化公共事件: data: ' + JSON.stringify(data)) 127 // 监听到语言切换后,需要重新绘制Canvas内容 128 this.drawText(); 129 }) 130 } else { 131 console.error(`MayTest Need create subscriber`); 132 } 133 }) 134 } 135 136 drawText(): void { 137 console.error("MayTest drawText") 138 this.context.reset() 139 this.context.direction = "inherit" 140 this.context.font = '30px sans-serif' 141 this.context.fillText("ab%123&*@", 50, 50) 142 } 143 144 build() { 145 Row() { 146 Canvas(this.context) 147 .direction(Direction.Auto) 148 .width("100%") 149 .height("100%") 150 .onReady(() =>{ 151 this.drawText() 152 }) 153 .backgroundColor(Color.Pink) 154 } 155 .height('100%') 156 } 157 158} 159``` 160 161| 镜像前 | 镜像后 | 162| ----------- | ----------------------------------- | 163||| 164 165### 镜像状态字符对齐 166[Direction](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#direction)是指文字的方向,即文本在屏幕上呈现时字符的顺序。在从左到右(LTR)文本中,显示顺序是从左向右;在从右到左(RTL)文本中,显示顺序是从右向左。 167 168[TextAlign](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#textalign)是将文本作为一个整体,在布局上的影响,具体位置会受Direction影响,以TextAlign为start为例,当Direction为LTR时,布局位置靠左;当Direction为RTL时,布局位置靠右。 169 170在LTR与RTL文本混排时,如一个英文句子中包含阿拉伯语的单词或短语,显示顺序将变得复杂。下图为数字和维吾尔语混合时对应的字符逻辑顺序。 171 172 173 174此时,文本渲染引擎会采用名为“双向算法”或“Unicode双向算法”(Unicode Bidirectional Algorithm)的方法来确定字符的显示顺序。下图展示了LTR与RTL文本混合时对应的字符显示顺序,确定字符方向的基本原则如下: 1751. 强字符的方向性:强字符具有明确的方向性,例如,中文为LTR,阿拉伯语为RTL,这类字符的方向性会影响其周围的中性字符。 176 1772. 弱字符的方向性:弱字符不具备明确的方向性,这些字符不会影响其周围中性字符的方向。 178 1793. 中性字符的方向性:中性字符无固定方向性,它们会继承其最近的强字符的方向;若附近无强字符,则采用全局方向。 180 181