Ao localizar o serviço, é importante considerar cuidadosamente a coordenação das transferências entre si. O chefe da equipe de desenvolvimento Android do cliente Yandex.Taxi, Alexander Bonel, falou sobre as práticas e ferramentas que simplificam a localização. Na segunda parte do relatório, Sasha compartilhou a experiência de oferecer suporte à RTL no aplicativo: o que é bom e o que não funciona para o Android imediatamente, que problemas surgem devido ao suporte à RTL e como minimizá-los no futuro.
- No meu relatório, quero dizer quais idéias e práticas básicas usamos nas equipes de desenvolvimento de aplicativos móveis Táxis para resolver problemas relacionados à localização e atualização de traduções em nossos aplicativos. Depois, mostrarei como implementamos o suporte para trabalhar no modo de desenho, da direita para a esquerda no aplicativo.

Vou começar com a localização. Antes de mais, gostaria de esclarecer a terminologia. De acordo com minhas observações, um grande número de pessoas acredita que a localização é limitada apenas a traduções, embora, de fato, também resolva os problemas associados à formatação de números, datas, horas, trabalho com texto e símbolos, aspectos legais, entrega de conteúdo ao consumidor de tal maneira que ele tinha valor semântico para ele e não era percebido ambiguamente. E muito mais
(Comunicação com o público sobre quem tem quantos idiomas há suporte nos aplicativos - ed.)Quero contar uma história que aconteceu conosco em 2014. Em seguida, fizemos uma grande reformulação no aplicativo Taxi. Em um dos próximos lançamentos, demos aos usuários a oportunidade de indicar o número da entrada, além de observar essas informações na tela de informações da viagem e, mais importante, na tela de classificação de pedidos, que mostramos a todos os usuários, porque definitivamente queríamos obter uma classificação para a viagem. .

Naquela época, éramos bastante frívolos sobre o processo de localização e as traduções. Na maior parte, todo o processo foi manual. A atualização dos textos nos arquivos XML necessários, a adição de novas traduções foi realizada manualmente. E o fator humano desempenhou um papel. O desenvolvedor determinou a próxima transferência não no local padrão. Isso levou ao fato de que, para usuários com um código de idioma do sistema diferente do idioma russo, se solicitassem a entrada, o aplicativo travaria no final da viagem. E as pessoas não podiam fazer outro pedido.
Naquela época, tínhamos dois idiomas suportados no aplicativo: russo e inglês. E trabalhamos apenas na Rússia em três cidades: Moscou, Ecaterimburgo, São Petersburgo.

Atualmente, operamos em 16 países e são traduzidos para 18 idiomas. Eu acho que você entende todo o problema, se estivéssemos naquele estado naquele momento. Nós já percebemos que algo precisava ser mudado.

No Yandex, a maioria dos desenvolvedores de aplicativos móveis usa o serviço desenvolvido internamente para resolver problemas relacionados à localização. Possui uma interface de interface do usuário muito conveniente, é possível definir seu projeto, definir um conjunto de chaves, um conjunto de idiomas para o qual você precisa traduzir o projeto. E depois que as traduções aparecerem, elas poderão ser carregadas em qualquer formato conveniente. Ele também tem uma integração muito boa com nossos serviços internos. Há controle de versão. Mas para mim, pessoalmente, como desenvolvedor, o mais importante é ter uma API, porque já sugere que todo o trabalho manual relacionado a traduções possa ser automatizado. O que nós fizemos. Nós desenvolvemos um plugin para Gradle. De fato, a atualização da tradução no aplicativo agora se resume ao fato de o desenvolvedor executar uma única tarefa: updateTranslations.

Em uma primeira aproximação, ele vai para um serviço de localização. Verifica se há traduções atualizadas, carrega-as no projeto e as coloca nos arquivos necessários. Além disso, ele também verifica o status das traduções no serviço de localização em relação ao que está agora no projeto.

Na próxima vez que o status do git for executado, o desenvolvedor verá em seu diretório de trabalho quais arquivos foram alterados.

Ele também pode procurar no relatório HTML gerado sobre qual chave para qual valor em qual idioma foi alterado.

E ele também pode ver quais problemas estão atualmente presentes nas traduções de seu projeto.

O plugin é configurável. Podemos determinar o número de idiomas que nosso aplicativo suporta. É muito importante que os localizadores iniciem um novo idioma, e ele inadvertidamente se infiltre no projeto, sem passar pela revisão e revisão.

Há também um recurso de remapeamento específico. Falarei sobre isso um pouco mais tarde, em mais detalhes, quando falar sobre RTL.
Quais problemas esse plug-in analisa agora? O problema que encontramos em 2014 é comum, falta de tradução. Agora, para adicionar uma nova linha, uma nova tradução ao projeto, não basta o desenvolvedor defini-la no arquivo XML.

Em primeiro lugar, se ele não fizer isso no local padrão, sua chave recém-enrolada simplesmente desaparecerá durante a próxima sincronização, e ele saberá sobre isso no estágio de compilação.

Se ele determinar a chave no arquivo padrão, mas se esquecer de fazê-lo no serviço de localização, na próxima vez em que as atualizações de atualização forem executadas, ele receberá um erro do plug-in, que lhe dirá: “Essa chave está no seu projeto, mas não está no serviço de localização, está lá precisa começar. "

O segundo problema típico é a falta de tradução. Obtemos uma lista de links para as chaves para as quais não há tradução e, como regra, os encaminhamos ao nosso gerente para que posteriormente estabeleçam a comunicação com os tradutores. O terceiro ponto geralmente ocorre quando eles decidem reconsiderar o uso de argumentos de formato de alguma maneira e, por exemplo, em vez de um formato inteiro, eles começaram a usar o formato de string.
Mas, ao mesmo tempo, em algumas traduções eles esqueceram de alterar o número na linha.

E o quarto problema também é causado pelo fator humano, principalmente na tradução. Se caracteres Unicode são usados na tradução, é muito fácil ficar confuso no posicionamento dos caracteres e, em vez de um espaço inextricável, obter uma hifenização para outra linha - é disso que estamos tentando nos livrar.
Isso é tudo sobre localização.
Agora, quero falar sobre a experiência de implementar o suporte para renderização da direita para a esquerda no aplicativo usando o exemplo de Israel. Lançamos em 2018 com a marca Yango em Israel. Como se viu, em Israel as pessoas leem de maneira diferente do que você e eu. Eles lêem da direita para a esquerda.

Por onde você quer começar? Com o Android, em princípio, o suporte de renderização da direita para a esquerda é implementado rapidamente.
Começa com o fato de que, no manifesto do aplicativo, no elemento Application, você precisa declarar o atributo supportRtl = "true". Mas quero agradar a você: se você integrar o SDK do Facebook para autorização social em seus aplicativos, os desenvolvedores atenciosos do Facebook já fizeram isso por você. E se você não validar o manifesto ao mesclar, esse atributo com o valor true se ajustará ao seu aplicativo, e ele já poderá fazê-lo em Rtl. Isso é algo para se pensar.
Eu acho que a maioria das pessoas sentadas na platéia provavelmente tem suporte mínimo para o Android 4.4. Alguém tem mais sorte - isso é 5.0 e superior. Alguém poderia ser menos afortunado, e eles suportam 4.0, ou, Deus permita, 2.3. Nesse caso, você terá grandes problemas, porque o suporte completo a Rtl no Android apareceu desde a versão 4.2. Portanto, com o minSdk 17, você simplificará sua vida por uma ordem de magnitude.
A transferência de um projeto para trabalhar com Rtl começa com a ferramenta de refatoração no Android Studio - Adicione suporte a RTL sempre que possível. Devemos prestar homenagem, funciona muito bem. Ele examina os arquivos XML da sua marcação, analisa a presença de atributos com valores esquerdo e direito para gravidade, preenchimentos, margens e os substitui pelo início e fim. Se você deseja ver como o aplicativo funciona por padrão no modo da direita para a esquerda, não precisa ter conteúdo com os chamados caracteres fortes de RTL - em hebraico ou árabe. Você só precisa habilitar Forçar direção do layout RTL nas configurações do desenvolvedor.
Quais são as opções para personalizar a interface do usuário e renderizar o texto que o Android fornece para RTL?

O primeiro ponto é o atributo layoutDirection, que usa a opção Force Force RTL Layout Direction descrita. Ela tem apenas quatro significados possíveis. Ou seja, por padrão é herdado do pai. Podemos dizer que o layout é desenhado com base na localidade selecionada. Você pode dizer claramente que é desenhado da direita para a esquerda ou da esquerda para a direita.
O segundo elemento que muitas pessoas provavelmente ignoram por hábito quando se envolvem no alinhamento de texto é textAlignment. Muitos ainda continuam usando a gravidade. Não use gravidade para alinhar o texto, mas use textAlignment.
O terceiro atributo é a direção de renderização do texto, textDirection. Tem uma configuração bastante flexível. Ele permite que você determine como o texto é renderizado, dependendo de qual primeiro caractere forte está no texto, seja do conjunto de caracteres LTR fortes em latim ou da RTL forte em hebraico. Porém, se você suporta totalmente o RTL no aplicativo, não precisa ignorá-lo, pois ignora um artefato engraçado.

Este é um ovo de páscoa ou é um efeito colateral na implementação do editText: sua dica no editText começa a se dispersar. Portanto, em qualquer caso, você deve definir algum valor para ele.

Se você precisar observar uma certa renderização de alguns recursos gráficos ou marcações no modo RTL, o Android fornecerá a capacidade de definir o qualificador ldrtl no seu pai, no qual você pode colocar qualquer recurso, e ele será desenhado no modo de renderização RTL conforme especificado.
Às vezes, é necessário que o tempo de execução desenhe o texto proveniente do back-end, como está, como veio, ignorando o modo em que seu aplicativo está atualmente trabalhando. De fato, no renderizador de texto, isso é feito devido ao fato de o texto ser enquadrado pelos chamados caracteres de controle Bidi Unicode. A lógica para trabalhar com esses caracteres em si contém a classe BidiFormatter, fornecendo apenas um método unicodeWrap. Ele usa CharSequence como entrada e retorna uma string emoldurada por esses caracteres. Há um número exaustivo deles e, em princípio, deve resolver a maioria dos seus problemas.
Mas se houver algo tão específico, o w3.org tem um
bom artigo sobre como usar esses símbolos.
Que problemas tivemos quando iniciamos o suporte a RTL em nosso aplicativo? Primeiro de tudo, é um conflito de padrões de localização.
O BCP47 é um padrão de localização mais recente, que mudou os códigos de alguns códigos de idioma. E o fato é que há um problema com a classe Java do código do idioma. Ele funciona por padrão no modo de compatibilidade com versões anteriores e converte códigos de localidade do BCP para ele em ISO. Ou seja, vimos isso quando o código iw em vez do código he começou a ir para o nosso back-end no cabeçalho Accept-Language.

Se você se lembra do slide com a configuração do nosso plugin, era necessário remapear apenas para isso - para traduzir o conteúdo de he para iw.
Se você precisar usar o formato BCP, isso será totalmente implementado no projeto Apache Cordova. Eles têm uma classe Globalization e uma implementação de localeToBcp47Language.

Outro ponto que "entrega" com suporte a RTL no aplicativo são as animações. Aqui, o benefício é, de fato, apenas as animações ao longo do eixo X são afetadas, e talvez a única solução ou abordagem que o ajude a evitar mais problemas seja a capacidade de reconsiderar as animações absolutas na direção das animações relativas.
Um problema que talvez seja resolvido apenas pela reflexão, porque é rigidamente implementado no próprio componente é o alinhamento de dicas do TextInputLayout. O fato é que, se a dica for especificada em caracteres fortes RTL em hebraico, ela estará claramente alinhada à direita, mesmo que o conteúdo digitado no texto de edição possa ser de caracteres latinos. E vice-versa. Se sua dica estiver em latim, ela estará claramente alinhada à esquerda. Isso só pode ser resolvido com reflexão.

Por fim, depois de implementar o RTL em seu aplicativo, faz sentido reconsiderar as severidades dos problemas de RTL que o Lint analisa. Existem apenas quatro deles. Se você não suporta RTL em seu aplicativo, mas usa explicitamente atributos específicos de RTL em algum lugar, então este é RtlEnabled (o Lint falará sobre isso).

Se você suporta RTL no aplicativo, mas o minSdkVersion do aplicativo é menor que 17, também deve continuar usando atributos do tipo esquerdo e direito, não é possível usar apenas os atributos de início e fim na sua marcação. É isso que o RtlCompat analisa. RtlSymmetry jura quando vê paddings assimétricos. Em geral, minha opinião é que o aapt, ao processar recursos, deve falhar se se deparar com preenchimentos simétricos. Se você precisar de algum tipo de acesso assimétrico, use margens como um parâmetro de layout completo.
Finalmente, o quarto problema é o RTL codificado. Isso é apenas que nos atributos apenas os valores de esquerda e direita são indicados. Essencialmente, isso anula a ferramenta de refatoração Adicionar suporte a RTL sempre que possível. Tudo vem do Lint ao entrar no RTL. Uma implementação de análise também está disponível no AOSP na classe RtlDetector. Ou seja, se a imaginação permitir, você pode criar algo próprio, observando como a análise está acontecendo agora.
Meu relatório está chegando ao fim. Quero fazer algumas teses sobre a construção da localização correta em nosso aplicativo, para a qual chegamos ao longo do tempo.

Antes de tudo, no início do projeto, pense em internacionalização. Eu realmente não mencionei isso. Isso não é o mesmo que localização. De fato, a internacionalização possibilita a localização na aplicação, no produto. Isso funciona imediatamente em Java devido ao suporte completo a Unicode e no Android - devido ao seu rico sistema de recursos. Talvez a única coisa que possa acontecer aqui seja nossa fixação como desenvolvedores sobre o tema: "Eu escrevo o aplicativo apenas para russo, o que significa que só o verificarei no idioma russo". E quando você começa a usar os idiomas armênio, georgiano, hebraico ou árabe no aplicativo, a imagem parece completamente diferente e mostra o seu paradigma usual.
Segundo momento. Considere incorporar a localização no seu IC. É muito decepcionante aprender sobre os problemas associados às traduções durante a fase de teste do candidato a lançamento, para a qual você pode se preparar por várias semanas. Ou seja, agora estamos executando esta tarefa para cada solicitação de pool, para que possamos ter certeza de que tudo está bem com as traduções e que podemos congelar o novo código na ramificação principal do projeto.
O terceiro ponto. Respeite o trabalho dos tradutores e seu orçamento. Primeiro, exclua os recursos não utilizados porque as pessoas podem continuar gastando tempo e dinheiro traduzindo seqüências que você não utiliza no seu projeto. Em segundo lugar, siga as traduções que estão no seu repositório no serviço de localização, mas que não estão no seu código.
Idealmente, se a API do seu serviço de localização fornecer informações sobre quando uma chave específica foi aberta, e você poderá usar heurísticas como "Se a chave foi aberta há mais de um mês", verifique sua presença na revisão mais recente do brunch principal. Se ele não estiver lá, provavelmente, este é um candidato claro para removê-lo e para que os localizadores não gastem tempo com ele.
Um candidato mais ou menos universal a uma bala de prata é armazenar seqüências de caracteres no back-end, e não no cliente. No mínimo, isso lhe dará a oportunidade de mantê-los sempre relevantes no lado do aplicativo.
Temos um público-alvo muito diversificado, todos percebem o mundo e o conteúdo do aplicativo à sua maneira. Nossa tarefa como desenvolvedores é ajudar a manter essa percepção. Meu relatório sobre isso acabou. Muito obrigado!