在Android Studio中为所有硬编码字符串自动生成@String引用

在Android Studio中为所有硬编码字符串自动生成@String引用,android,android-studio,android-resources,Android,Android Studio,Android Resources,当我开始编写我的项目时,我不知道字符串资源。现在我想将此资源用于所有字符串。你是怎么突然做到的?知道我目前有10000多个字符串,我不想一个接一个地手动完成…我不认为有一个巧妙的解决方法,即您需要以某种方式使用唯一且有用的标识符命名所有字符串。当你让它自动完成时,你的代码会变得很难阅读:/我不认为有一个巧妙的解决方法,你需要用一个唯一的有用的标识符来命名所有的字符串。当您自动执行此操作时,您的代码将变得很难阅读:/只需突出显示字符串的每个实例,然后单击语句左侧的黄色提示图标以提取字符串资源。然后

当我开始编写我的项目时,我不知道字符串资源。现在我想将此资源用于所有字符串。你是怎么突然做到的?知道我目前有10000多个字符串,我不想一个接一个地手动完成…

我不认为有一个巧妙的解决方法,即您需要以某种方式使用唯一且有用的标识符命名所有字符串。当你让它自动完成时,你的代码会变得很难阅读:/

我不认为有一个巧妙的解决方法,你需要用一个唯一的有用的标识符来命名所有的字符串。当您自动执行此操作时,您的代码将变得很难阅读:/

只需突出显示字符串的每个实例,然后单击语句左侧的黄色提示图标以提取字符串资源。然后您可以稍后删除重复的字符串。

只需突出显示字符串的每个实例,然后单击Statemennt左侧的黄色提示图标以提取字符串资源。然后您可以稍后删除重复的字符串。

要完全自动化此操作,您需要一个特殊工具(我还没有找到),在Android Studio之外:

  • 查找字符串(并替换为引用)
  • 更新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