在Android Studio中为所有硬编码字符串自动生成@String引用
当我开始编写我的项目时,我不知道字符串资源。现在我想将此资源用于所有字符串。你是怎么突然做到的?知道我目前有10000多个字符串,我不想一个接一个地手动完成…我不认为有一个巧妙的解决方法,即您需要以某种方式使用唯一且有用的标识符命名所有字符串。当你让它自动完成时,你的代码会变得很难阅读:/我不认为有一个巧妙的解决方法,你需要用一个唯一的有用的标识符来命名所有的字符串。当您自动执行此操作时,您的代码将变得很难阅读:/只需突出显示字符串的每个实例,然后单击语句左侧的黄色提示图标以提取字符串资源。然后您可以稍后删除重复的字符串。只需突出显示字符串的每个实例,然后单击Statemennt左侧的黄色提示图标以提取字符串资源。然后您可以稍后删除重复的字符串。要完全自动化此操作,您需要一个特殊工具(我还没有找到),在Android Studio之外:在Android Studio中为所有硬编码字符串自动生成@String引用,android,android-studio,android-resources,Android,Android Studio,Android Resources,当我开始编写我的项目时,我不知道字符串资源。现在我想将此资源用于所有字符串。你是怎么突然做到的?知道我目前有10000多个字符串,我不想一个接一个地手动完成…我不认为有一个巧妙的解决方法,即您需要以某种方式使用唯一且有用的标识符命名所有字符串。当你让它自动完成时,你的代码会变得很难阅读:/我不认为有一个巧妙的解决方法,你需要用一个唯一的有用的标识符来命名所有的字符串。当您自动执行此操作时,您的代码将变得很难阅读:/只需突出显示字符串的每个实例,然后单击语句左侧的黄色提示图标以提取字符串资源。然后
- 查找字符串(并替换为引用)
- 更新strings.xml
- 可选地翻译字符串
对于一次手动提取一个(另请参见):
Alt+Enter,提取字符串资源,而插入符号位于代码中硬编码字符串的内部:
在XML中:
要完全自动化,您需要一个特殊工具(我还没有找到),在Android Studio之外:
- 查找字符串(并替换为引用)
- 更新strings.xml
- 可选地翻译字符串
对于一次手动提取一个(另请参见):
Alt+Enter,提取字符串资源,而插入符号位于代码中硬编码字符串的内部:
在XML中:
我至少为xml布局编写了一个java脚本,供任何需要它的人使用。。。以后可能需要一些小的修复
package com.cameron.smelevel.lib;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class StringResourceCreator {
public static void main(String [] args){
String mainDirPath = "S:\\androidProject\\src";
String layoutDirPath = "\\main\\res\\layout";
String outputDirPath = mainDirPath+"-out";
String stringFilePath = outputDirPath+"\\strings.txt";
String line;
File layoutDir = new File(mainDirPath + layoutDirPath);
File layoutOutDir = new File(outputDirPath + layoutDirPath);
layoutOutDir.mkdirs();
HashMap<String, String> stringEnteries = new HashMap<>();
for (File file : layoutDir.listFiles()) {
String fileName = file.getName();
PrintWriter pr = null;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(file);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
FileWriter outputStream = new FileWriter(layoutOutDir.getAbsolutePath() + "\\"+ fileName);
pr = new PrintWriter(outputStream);
while ((line = bufferedReader.readLine()) != null) {
line = getModifiedLine(line, stringEnteries);
pr.write(line);
pr.println();
}
} catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" + fileName + "'");
} catch (IOException ex) {
System.out.println("Error reading file '" + fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}finally {
if(pr != null) pr.close();
}
}
PrintWriter pr = null;
try {
FileWriter outputStream = new FileWriter(stringFilePath);
pr = new PrintWriter(outputStream);
Iterator it = stringEnteries.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
String entry = "<string name=\"" + pair.getKey() + "\">" + pair.getValue() + "</string>";
it.remove(); // avoids a ConcurrentModificationException
pr.write(entry);
pr.println();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(pr != null) pr.close();
}
}
private static String getModifiedLine(String line, HashMap<String, String> stringEnteries) {
if (line.contains(":text=\"") || line.contains(":hint=\"")){
StringBuilder fieldName = new StringBuilder();
String text = line.substring(line.indexOf("\"")+1, line.lastIndexOf("\""));
String textTrimmed = text.replace("\\n","");
if (!textTrimmed.startsWith("@string")){
String[] words = textTrimmed.split(" ");
for (int j = 0; j < words.length; j++) {
String word = words[j];
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (Character.isAlphabetic(c))
if (i == 0 && fieldName.length() != 0)
fieldName.append(Character.toUpperCase(c));
else
fieldName.append(Character.toLowerCase(c));
}
}
if (fieldName.length() > 1) {
String value = stringEnteries.get(fieldName.toString());
if(value != null) {
if (!value.equals(text)) {
fieldName.append("1");
stringEnteries.put(fieldName.toString(), text);
}
}else
stringEnteries.put(fieldName.toString(), text);
line = line.replace(text, "@string/"+fieldName);//replaceLast(line, text, "@string/"+fieldName);
}
}
}
return line;
}
}
package com.cameron.smelevel.lib;
导入java.io.BufferedReader;
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.FileReader;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.io.PrintWriter;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.Iterator;
导入java.util.Map;
公共类StringResourceCreator{
公共静态void main(字符串[]args){
字符串mainDirPath=“S:\\androidProject\\src”;
字符串layoutDirPath=“\\main\\res\\layout”;
字符串outputDirPath=mainDirPath+“-out”;
String stringFilePath=outputDirPath+“\\strings.txt”;
弦线;
文件layoutDir=新文件(mainDirPath+layoutDirPath);
文件layoutOutDir=新文件(outputDirPath+layoutDirPath);
layoututdir.mkdirs();
HashMap StringEntries=新HashMap();
对于(文件:layoutDir.listFiles()){
字符串文件名=file.getName();
PrintWriter pr=null;
试一试{
//FileReader以默认编码读取文本文件。
FileReader FileReader=新的FileReader(文件);
//始终将文件读取器包装在BufferedReader中。
BufferedReader BufferedReader=新的BufferedReader(文件阅读器);
FileWriter outputStream=新的FileWriter(layoutOutDir.getAbsolutePath()+“\\”+文件名);
pr=新的PrintWriter(outputStream);
而((line=bufferedReader.readLine())!=null){
line=getModifiedLine(线、细线);
pr.write(行);
pr.println();
}
}捕获(FileNotFoundException ex){
System.out.println(“无法打开文件“”+fileName+”);
}捕获(IOEX异常){
System.out.println(“读取文件“+”文件名“+”时出错”);
//或者我们可以这样做:
//例如printStackTrace();
}最后{
如果(pr!=null)pr.close();
}
}
PrintWriter pr=null;
试一试{
FileWriter outputStream=新的FileWriter(stringFilePath);
pr=新的PrintWriter(outputStream);
迭代器it=StringEntries.entrySet().Iterator();
while(it.hasNext()){
Map.Entry对=(Map.Entry)it.next();
String entry=“”+pair.getValue()+”;
it.remove();//避免ConcurrentModificationException
pr.write(条目);
pr.println();
}
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}最后{
如果(pr!=null)pr.close();
}
}
私有静态字符串getModifiedLine(字符串行、HashMap StringEntries){
if(line.contains(“:text=\”)| line.contains(“:hint=\”){
StringBuilder fieldName=新建StringBuilder();
String text=line.substring(line.indexOf(“\”)+1,line.lastIndexOf(“\”);
字符串textrimmed=text.replace(\\n,“”);
如果(!textrimmed.startsWith(“@string”)){
String[]words=textTrimmed.split(“”);
for(int j=0;j