Android整理需要翻译的strings资源详情
1、问题描述
项目需要做俄语国际化,历史代码里有的字段有俄语翻译、有的没有,需要把没翻译的中文整理出来翻译成俄文。 (因为项目组件化module
太多了所以觉得一个一个整理很麻烦,如果module不多的话就可以直接手动处理不用整下面这些了)
2、大概思路
- 列出所有
res
目录,根据是否包含values-ru
分成两组(半自动) - 在“不包含”分组里把需要翻译的中文文件复制出来(半自动)
- 在“包含”组里把需要补充翻译的字段复制出来(纯手动)
- 把复制出来需要翻译的
xml
文件转换成excel
用于翻译(自动) - 把翻译好的文件通过
excel
的公式转换成xml
,根据之前记录的res目录放到项目里(半自动)
3、代码解析
列出所有string.xml文件路径
public static void listResPath(String src) throws Exception { File path1 = new File(src); if (!path1.exists()) { return; } File[] items = path1.listFiles(); if (items == null) return; for (File item : items) { if (item.isFile()) { if (!item.getName().equals("strings.xml")) continue; System.out.println(item.getPath()); } else { listResPath(item.getPath()); } } }
手工找出不包含ru的模块,然后在项目里看一下应该翻译哪个文件,把需要翻译的文件路径放到一个txt里,例如:
D:\work\aaa\src\main\res\values-zh-rCN\strings.xml D:\work\bbb\src\main\res\values-zh-rCN\strings.xml D:\work\ccc\src\main\res\values\strings.xml D:\work\ddd\src\main\res\values-zh\strings.xml
复制这些文件到translate文件夹
private static List<String> needCopyFiles = new ArrayList<>(); private static void getNeedCopyFiles() { try { FileInputStream inputStream = new FileInputStream("D:\xxx\needCopy.txt"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String str; while ((str = bufferedReader.readLine()) != null) { if (!str.isEmpty()) { needCopyFiles.add(str); } } bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } public static void listResPath(String src) throws Exception { File path1 = new File(src); File path2 = new File("D:\xxx\translate"); if (!path1.exists()) { return; } File[] items = path1.listFiles(); if (items == null) return; for (File item : items) { if (item.isFile()) { if (!item.getName().equals("strings.xml")) continue; if (needCopyFiles.contains(item.getPath())) { System.out.println(item.getPath()); FileInputStream fis = new FileInputStream(item); String[] dir = item.getPath().split("\\"); String fileName = dir[7]+dir[8]+".xml"; FileOutputStream fos = new FileOutputStream(path2 + File.separator + fileName); byte[] b = new byte[1024]; for (int i=0; (i=fis.read(b))!=-1;) { fos.write(b,0,i); fos.flush(); } fos.close(); fis.close(); } } else { listResPath(item.getPath()); } } }
手工找出包含ru的模块,在项目里看一下需要补充翻译哪些字段,复制这些字段到新建的xml文件里,把这些xml文件也放在translate
文件夹。
把translate文件夹里的文件读取到excel
import com.alibaba.excel.EasyExcel; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.File; import java.util.*; public class Strings2Excel { private static final List<ExcelDataBean> excelDataBeanList = new ArrayList<>(); public static void main(String[] args) { try { traverseFile("D:\xxx\translate"); write2Excel(); } catch (Exception e) { e.printStackTrace(); } } private static void write2Excel() { String dst = "D:\xxx\res.xlsx"; System.out.println("excel list size: " + excelDataBeanList.size()); EasyExcel.write(dst, ExcelDataBean.class).sheet("value").doWrite(excelDataBeanList); } public static void traverseFile(String src) throws Exception { File path1 = new File(src); if (!path1.exists()) { System.out.println("源路径不存在"); return; } File[] items = path1.listFiles(); if (items == null) return; for (File item : items) { readXml(item); } } private static void readXml(File file) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(file); Element rootElement = document.getRootElement(); Iterator<Element> iterator = rootElement.elementIterator(); while (iterator.hasNext()) { Element child = iterator.next(); String name = child.attribute(0).getValue(); String value = child.getStringValue(); System.out.println(name + " = " + value); excelDataBeanList.add(new ExcelDataBean(name, value)); } } }
@Data public class ExcelDataBean { private String name; private String value; private String translate; }
需要引入的依赖:
<dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.4</version> </dependency> <!--xls--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j --> <dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.5</version> </dependency> </dependencies>
因为不同模块可能会有重复的中文字段,翻译的同事是去重了翻译的,所以拿到翻译好了的excel
之后,要把重复的翻译填充一下。思路是读取翻译前的文件到excelDataBeanList
、读取翻译后的文件到translatedList
,根据两个列表中相同的中文字段填充excelDataBeanList
的俄文字段然后输出到新文件。
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import java.io.File; import java.util.ArrayList; import java.util.List; public class FillTranslated { private static final List<ExcelDataBean> excelDataBeanList = new ArrayList<>(); private static final List<ExcelDataBean> translatedList = new ArrayList<>(); public static void main(String[] args) { try { readRes("D:\xxx\res.xlsx"); } catch (Exception e) { e.printStackTrace(); } } private static void readRes(String s) { File file = new File(s); EasyExcel.read(file, ExcelDataBean.class, new AnalysisEventListener<ExcelDataBean>() { @Override public void invoke(ExcelDataBean bean, AnalysisContext analysisContext) { excelDataBeanList.add(bean); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { readTranslated("D:\xxx\translated.xlsx"); } }).sheet().doRead(); } private static void readTranslated(String s) { File file = new File(s); //这个read其实是按列读的,并不是根据列标题和类属性名称匹配的 EasyExcel.read(file, ExcelDataBean.class, new AnalysisEventListener<ExcelDataBean>() { @Override public void invoke(ExcelDataBean bean, AnalysisContext analysisContext) { translatedList.add(bean); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { fillTranslated(); write2Excel(); } }).sheet().doRead(); } private static void fillTranslated() { for (ExcelDataBean bean : translatedList) { excelDataBeanList.forEach(a -> { if (a.getValue() != null && a.getValue().equals(bean.getValue())) { a.setTranslate(bean.getTranslate()); } }); } } private static void write2Excel() { String dst = "D:\xxx\翻译字段.xlsx"; System.out.println("excel list size: " + excelDataBeanList.size()); EasyExcel.write(dst, ExcelDataBean.class).sheet("value").doWrite(excelDataBeanList); } }
把excel转换成xml
A列 | B | C | H | K |
---|---|---|---|---|
name | value | translate | 给name加双引号 | 拼接xml里的string |
detail_up | 收起 | убрать | =""""&A2&"""" | ="<string name="&H2&">"&C2&"</string>" |
到此这篇关于Android整理需要翻译的strings资源详情的文章就介绍到这了,更多相关Android整理需要翻译的strings资源内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
- 首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
- 下面来给各位简单的介绍一下关于Android开发之PhoneGap打包及错误解决办法,希望碰到此类问题的同学可进入参考一下哦。 在我安装、配置好PhoneGap项目的所有依赖...2016-09-20
用Intel HAXM给Android模拟器Emulator加速
Android 模拟器 Emulator 速度真心不给力,, 现在我们来介绍使用 Intel HAXM 技术为 Android 模拟器加速,使模拟器运行度与真机比肩。 周末试玩了一下在Eclipse中使...2016-09-20- 在安卓开发时我碰到一个问题就是需要实现全屏,但又需要我们来判断出用户是使用了全屏或非全屏了,下面我分别找了两段代码,大家可参考。 先来看一个android屏幕全屏实...2016-09-20
Android开发中布局中的onClick简单完成多控件时的监听的利与弊
本文章来为各位介绍一篇关于Android开发中布局中的onClick简单完成多控件时的监听的利与弊的例子,希望这个例子能够帮助到各位朋友. 首先在一个控件加上这么一句:and...2016-09-20Ubuntu 系统下安装Android开发环境 Android Studio 1.0 步骤
Android Studio 是一个Android开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试,可以在Linux,Mac OS X,Window...2016-09-20- 这篇文章主要为大家详细介绍了Android实现简单用户注册案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-26