Flutter如何适配RTL

阿拉伯语和希伯来语等是使用的从右到左书写的文字系统。世界上估计有4.22亿人以阿拉伯语做为母语。使用从右至左的人口可以说是更多了。所以对于出海项目来说,是不能忽视的一部分。

RTL可以说是本地化适配中比较麻烦的一项,并没有多语言适配来的简单。RTL简单说就像视频开了“镜像”,但实际并没有这么简单粗暴,比如商品图片我们不可能镜像,但是返回按钮的箭头却需要翻转过来。

因为这方面适配国内不常做,所以相关资料比较少。我自己在采坑后,做了下面的整理,希望可以给到你帮助。

概览

这里我们可以先建立实现目标的效果,所以可以参考Material的双向设计指南

我列出一些效果图片,简单说明一下:

在这里插入图片描述

  • 代表方向元素的需要“镜像”,某些图标可能看起来有方向性,但它们实际上代表用右手握住一个物体,比如搜索图标的手柄通常位于右下角。所以不用处理。但如果是返回按钮,则需要。

  • 阿拉伯文字大部分但不完全是从右到左书写的;数学表达式、数字日期和数字单位仍使用从左到右的书写方式。例如图中的输入框,我们将文字排列方向改为了从右至左,此时用户输出英文等其他从左至右的语言时,需要遵循自己的规则。

需要注意的一些情况:
在这里插入图片描述

  • 不要镜像媒体播放按钮和进度条,因为它们指的是磁带播放的方向,而不是时间的方向。
  • 时钟仍然顺时针旋转。时钟图标或带有顺时针箭头的圆形刷新或进度指示器不应镜像。

适配

首先需要项目中接入intl,这部分我不过多介绍,可以参考官方文档。这里想说明的是如果当前语言设置为了从右到左的语言,例如阿拉伯语(Locale('ar')),那么Flutter就会自己翻转过来,我们不需要额外的进行设置。

因为GlobalWidgetsLocalizations帮我们做了适配。
在这里插入图片描述

所以对于自带的Widget,例如PageViewBottomNavigationBar,我们不需要做特殊处理,减轻了很多适配工作。

我们上面也提到了,实际适配中情况比较多,并不是简单的“镜像”。所以Flutter帮我们做的全局处理一定造成“误伤”。

如果你需要固定方向,可以使用Directionality Widget包裹,指定textDirection属性。如果是RowStackText等可以设置textDirection

Widget替换

适配之所以这么简单,主要是因为我们常用的Row等Widget里面的crossAxisAlignment方向并不是有明确方向性的left、right,而是start、end。

如果反过来想,适配可能有问题的地方就是我们代码中指定left、right的地方。比如我们常用的EdgeInsets.only(left: 12)AlignAlignment.centerRightPositioned

我下面列出一些对应的替代方法,我们可以在平时的开发中就养成习惯,使用这些Widget。做到更好的兼容性。

  • Positioned -> PositionedDirectional
Positioned(
  left: 50,
  child: RedBox(),
),
  
PositionedDirectional(
  start: 50,
  child: RedBox(),
),
  • Alignment -> AlignmentDirectional
Align(
  alignment: Alignment.centerRight,
  child: RedBox(),
),
    
Align(
  alignment: AlignmentDirectional.centerEnd,
  child: RedBox(),
),
  • EdgeInsets -> EdgeInsetsDirectional
Padding(
  padding: EdgeInsets.only(right: 10),
  child: RedBox(),
),
  
Padding(
  padding: EdgeInsetsDirectional.only(end: 10),
  child: RedBox(),
),
  • Border -> BorderDirectional
BoxDecoration(
  border: Border(left: BorderSide(width: 4)),
  color: Colors.red,
),
  
BoxDecoration(
  border: BorderDirectional(start: BorderSide(width: 4)),
  color: Colors.red,
),
  • BorderRadius -> BorderRadiusDirectional
BoxDecoration(
  borderRadius: BorderRadius.only(topLeft: Radius.circular(10)),
  color: Colors.red,
),
  
BoxDecoration(
  borderRadius: BorderRadiusDirectional.only(topStart: Radius.circular(10)),
  color: Colors.red,
),

方向判断

比如我们有一个返回按钮,此时需要翻转过来。可以使用Transform.scalewidget和Directionality.of(context)方法结合处理。

Transform.scale(
  scaleX: Directionality.of(context) == TextDirection.rtl ? -1 : 1,
  child: Image.asset("xxx"),
);

PS:使用Icon Widget可以使用textDirection属性处理。

混合文本

混合文本就是说,一段文字里有多种语言,例如他说‘Hello’,我说30%。这里面有中文,英文,数字。那么我们翻译后,得到的结果是قال Hello، قلت 30%,实际显示如下:

在这里插入图片描述

可以看到英文,数字的部分是保留原有的方向。这就是上面我们说到的如果是输入框,需要根据输入的语言,遵循各自的显示规则。

  • 输出或显示英文,数字时,从左到右显示。
  • 包含阿拉伯语时,从右到左显示。

例如TextTextField Widget一般不用指定textDirection属性,自动就会展示正确顺序。不过标点符合是个例外,例如What is your gender?会显示成?What is your gender。因为对于这个符号,无法确定你的语言,所以就使用了从右到左,放到了”末尾“。

再例如输入内容的时候,我们希望输入和书写的习惯是一致的,输入英文数字时从左到右,输入阿拉伯语是从右到左。

在这里插入图片描述

这里我们就可以使用intl中的Bidi.detectRtlDirectionality(text)方法,返回true就是TextDirection.rtl,false就是TextDirection.ltr。然后将方向结果设置到TextField中。

方便起见,可以使用auto_direction库处理。它的内部就是使用Bidi.detectRtlDirectionality方法实现的。

CustomPainter

CustomPainter绘制的位置都是固定的,所以可以参考图片翻转的方法处理。这样处理比较简单。

其他

  • 字体选择、行高、字间距也是需要考虑的。
  • 日历也是从右至左,需要考虑使用标准阿拉伯文数字还是东阿拉伯数字。
    在这里插入图片描述

适配这项工作要想简单,就是要在项目初期规划好,代码也要规范。例如暗黑模式适配,如果颜色都是各处写死,没有统一封装管理,等到适配的时候就是处处修改。RTL也是一样,如果初期就使用Directional相关的widget去实现,适配时也能轻松不少。

最后就是在实际适配中,可以多搜集一些规则,多看一些国外网站,App的效果作为参考。当然最好是有一个懂阿拉伯语的人,哈哈。

参考

  • Right to Left (RTL) in Flutter App - Developer’s Guide

  • 阿拉伯语本地国际化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/927898.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Django-xadmin】

时间长不用,会忘的系列 1、Django-xadmin后台字段显示处理 主要是修改每个模块下adminx.py文件 代码解释:第1行控制表单字段显示第2行控制列表字段显示第3行控制搜索条件第4行控制过滤条件第5行支持单个或多个字段信息修改第6行列表分页,每页显示多少行…

Pytest --capture 参数详解:如何控制测试执行过程中的输出行为

--capture 选项用于控制测试用例执行过程中标准输出(stdout)和标准错误输出(stderr)的捕获行为。 --capture 的选项值: fd(默认) 捕获文件描述符级别的输出(stdout 和 stderr&#x…

整合SSM框架:构建Java Web应用

目录 简介 项目结构 配置文件详解 db.properties mybatis-config.xml spring-mybatis.xml springmvc.xml web.xml pom.xml 整合步骤 为什么这样整合? 简介 SSM框架整合指的是Spring、Spring MVC和MyBatis三个开源框架的整合。这种整合方式在Java Web开发…

Solidity开发智能合约

05-Solidity开发智能合约 0 Solidity和智能合约 Solidity开发可运行的智能合约步骤: 源代码通过编译成字节码(Bytecode),同时会产生二进制接口规范(ABI) 通过交易将字节码部署到以太坊网络,部署…

Java基础之控制语句:开启编程逻辑之门

一、Java控制语句概述 Java 中的控制语句主要分为选择结构、循环结构和跳转语句三大类,它们在程序中起着至关重要的作用,能够决定程序的执行流程。 选择结构用于根据不同的条件执行不同的代码路径,主要包括 if 语句和 switch 语句。if 语句有…

Vue教程|搭建vue项目|Vue-CLI2.x 模板脚手架

一、项目构建环境准备 在构建Vue项目之前,需要搭建Node环境以及Vue-CLI脚手架,由于本篇文章为上一篇文章的补充,也是为了给大家分享更为完整的搭建vue项目方式,所以环境准备部分采用Vue教程|搭建vue项目|V…

shell脚本30个案例(五)

前言: 通过一个多月的shell学习,总共写出30个案例,分批次进行发布,这次总共发布了5个案例,希望能够对大家的学习和使用有所帮助,更多案例会在下期进行发布。 案例二十一、系统内核优化 1.问题&#xff1…

分布式集群下如何做到唯一序列号

优质博文:IT-BLOG-CN 分布式架构下,生成唯一序列号是设计系统常常会遇到的一个问题。例如,数据库使用分库分表的时候,当分成若干个sharding表后,如何能够快速拿到一个唯一序列号,是经常遇到的问题。实现思…

ChatGPT/AI辅助网络安全运营之-数据解压缩

在网络安全的世界中,经常会遇到各种压缩的数据,比如zip压缩,比如bzip2压缩,gzip压缩,xz压缩,7z压缩等。网络安全运营中需要对这些不同的压缩数据进行解压缩,解读其本意,本文将探索一…

C++小问题

怎么分辨const修饰的是谁 是限定谁不能被改变的? 在C中,const关键字的用途和位置非常关键,它决定了谁不能被修改。const可以修饰变量、指针、引用等不同的对象,并且具体的作用取决于const的修饰位置。理解const的规则能够帮助我们…

Docker中配置Mysql主从备份

Mysql配置主从备份 一、Docker中实现跨服务器主从备份二、配置步骤1.配置主库2.配置从库3.遇到问题3.其它使用到的命令 一、Docker中实现跨服务器主从备份 在 Docker 中配置 MySQL 主从备份主要通过 MySQL 主从复制实现 二、配置步骤 1.配置主库 # 进入mysql主库容器 docke…

下载maven 3.6.3并校验文件做md5或SHA512校验

一、下载Apache Maven 3.6.3 Apache Maven 3.6.3 官方下载链接: 二进制压缩包(推荐): ZIP格式: https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zipTAR.GZ格式: https://archive.apache.org/dist/…

C++趣味编程:基于树莓派Pico的模拟沙漏-倾斜开关与LED的互动实现

沙漏,作为一种古老的计时工具,利用重力让沙子通过狭小通道,形成了计时效果。在现代,我们可以通过电子元件模拟沙漏的工作原理。本项目利用树莓派Pico、倾斜开关和LED,实现了一个电子沙漏。以下是项目的详细技术解析与C++代码实现。 一、项目概述 1. 项目目标 通过倾斜开关…

pycharm链接neo4j(导入文件)

1.新建csv文件 2.写入文件 3.运行代码 import csv from py2neo import Graph, Node, Relationship# 连接到Neo4j数据库,使用Bolt协议 graph Graph("bolt://localhost:7687", auth("neo4j", "password"))# 读取CSV文件 with open(…

【C++】多线程

目录 一 概念 1 多线程 2 多进程与多线程 3 多线程理解 二 创建线程 1 thread 2 join() 和 detach() 3 this_thread 三 std::mutex 1 lock 和 unlock 2 lock_guard 3 unique_lock 四 condition_variable 五 std::atomic 一 概念 1 多线程 在C11之前&#xff0…

Kafka 图形化工具 Eagle安装

Kafka 图形化工具 Eagle 3.0.1版本安装 1、安装JDK jdk安装 2、安装kafka 如未安装kafka,需要先安装完kafka 3、下载kafka-eagle 官网下载地址 wget https://github.com/smartloli/kafka-eagle-bin/archive/v3.0.1.tar.gz #移动到安装目录 mv v3.0.1.tar.gz…

vue实现echarts饼图自动轮播

echarts官网:Examples - Apache ECharts echartsFn.ts 把echarts函数封装成一个文件 import * as echarts from "echarts";const seriesData [{"value": 12,"name": "过流报警"},{"value": 102,"name&qu…

CSS动画案例6

目录 一、介绍二、静态页面的布局1.HTML部分2.CSS 三、动画交互四、结束语 一、介绍 本节内容我们来仿照一个网站(戳我进网站)的进入页面时的doing动画部分,首先是大标题从最小变为最大,然后是副标题从下向上走,最后是…

Proteus8.17下载安装教程

Proteus是一款嵌入式系统仿真开发软件,实现了从原理图设计、单片机编程、系统仿真到PCB设计,真正实现了从概念到产品的完整设计,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,能够帮助用…

工作-k8s问题处理篇

前言:公司这边为集团,所以项目较多,我目前总负责的项目架构有十六个,其中还有海外项目,不过底下也有一定的细分,同事解决不了的问题会升级到我这,只k8s容器平台常用的就有三种,一种是…