Intellij 插件开发-AndroidStudio(三)-写入生成代码

目录

前言:

一 写入原理

二 示例代码

写入代码


Intellij 插件开发-AndroidStudio (零)番外

Intellij 插件开发-AndroidStudio(一)--环境构建

 Intellij 插件开发-AndroidStudio(二)-文件操作

 Intellij 插件开发-AndroidStudio(三)-写入生成代码

Intellij 插件开发-AndroidStudio(四)-添加类和模板

前言:

上章节中已经讲了如何从layout获取操作对象。那么接下来就是如何将我们需要的代码写入到目标文件中了。

一 写入原理

java类中,在intellij编辑器里,其实就是被他自己拆分成了不同类型的对象,如 class,method,field等。往java类里面添加代码,无非也就是添加这些东西。

关键字:PsiElementFactory、PsiClass、PsiStatement、PsiElement

PsiElementFactory 用于创建我们需要添加到java类,或者方法中的对象,不管我们要添加什么,都是需要通过他来构建一个待添加的对象

PsiClass 很好理解,就是操作类,这个可以是当前操作的类,也可以是内部类,甚至别的类。

PsiStatement 代码块对象,通常无语法限制。说白了就是插入一段任意代码

PsiElement 代码对象,通常有语法限制,如field对象,method对象等。

二 示例代码

写入代码

public static void loadFile(@NotNull Project project, Editor editor, PsiFile currentFile) throws IncorrectOperationException {

        DocumentUtil.writeInRunUndoTransparentAction(new Runnable() {
            @Override
            public void run() {
                String layoutName = editor.getSelectionModel().getSelectedText();
                PsiFile xmlFile = AndroidUtils.findXmlResource(project, layoutName);
                if (xmlFile == null) {
                    return;
                }
                //获取到layout中的view对象
                List<AndroidView> androidViews = AndroidUtils.getIDsFromXML(xmlFile);
                int offset = editor.getCaretModel().getOffset();
                //获取到正在编辑器中编辑的方法体。
                PsiElement psiElement = currentFile.findElementAt(offset);
                PsiStatement psiStatement = PsiTreeUtil.getParentOfType(psiElement, PsiStatement.class);
                //获取当前操作的java类
                PsiClass psiClass = PsiTreeUtil.getParentOfType(psiElement, PsiClass.class);
                //获取原来的成变量
                Set<String> fieldSet = new HashSet<String>();
                for (PsiField field : psiClass.getFields()) {
                    fieldSet.add(field.getName());
                }

                final Set<String> thisSet = new HashSet<String>();
                processElement(psiElement, thisSet);

                //获取当前工程的操作factory,要靠这个对象来进行添加对象的创建
                PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
                //导入android.view包
                JavaCommonUtils.importAndroidPackage(psiClass, project, "View");
                
                String clickStr = "private View.OnClickListener mOnClickListener = new View.OnClickListener() {" +
                        "        @Override\n" +
                        "        public void onClick(View v) {\n" +
                        "            switch (v.getId()) {\n" +
                        "                ";
                //遍历每个操作view,生成对应需要的代码。内部拼装方式,很好懂
                for (AndroidView v : androidViews) {
                    if (!fieldSet.contains(v.getFieldName())) {
                        String sb = "private " + v.getName() + " " + v.getFieldName() + ";";
                        psiClass.add(elementFactory.createFieldFromText(sb, psiClass));
                        JavaCommonUtils.importAndroidPackage(psiClass, project, v.getName());
                    }
                    if (!thisSet.contains(v.getFieldName())) {
                        clickStr = clickStr + "case " + v.getId() + ":\n\nbreak;";
                        String sb1;
                        sb1 = String.format("%s = (%s) findViewById(%s);", v.getFieldName(), v.getName(), v.getId());
                        PsiStatement statementFromText = elementFactory.createStatementFromText(sb1, null);
                        psiStatement.getParent().addAfter(statementFromText, psiStatement);
                        String sb2;
                        sb2 = String.format("%s.setOnClickListener(%s);", v.getFieldName(), "mOnClickListener");
                        PsiStatement clickStrStatement = elementFactory.createStatementFromText(sb2, null);
                        psiStatement.getParent().addAfter(clickStrStatement, psiStatement);

                    }

                }
                clickStr = clickStr + "default:\n" +
                        "                        break;\n" +
                        "            }\n" +
                        "        }\n" +
                        "    };";
                System.out.print(clickStr);
                //把拼装好的点击事件的对象添加到类中。
                PsiStatement clickText = elementFactory.createStatementFromText(clickStr, null);
                psiStatement.getParent().addAfter(clickText, psiElement);
                //CodeStyle
                   CodeStyleManager.getInstance(project).reformat(psiClass.getParent());

            }
        });

    }

猜你喜欢

转载自blog.csdn.net/shenjinalin123/article/details/82454013
今日推荐