Android IDE Plugin ViewInject

前言
目前为止,Android使用的插件的已经很多了,但是自己在这块确实空白的,之前写过了ViewInject博客了,在优化findViewById之后,考虑到不需要手写问题的情况下,采用插件辅助来开发,网上目前已经有了ButterKnife的辅助的插件,为自己开发ViewInject插件,个人建议不要光看我写的一部分我用到的方法,需要你自己看IDE Plugin API刚好这段时间有空闲时间。

使用
在使用本插件之前,请使用https://blog.csdn.net/u012127961/article/details/70195693
插件下载
插件项目
插件导入方法

技术
IDE Plugin API : http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/publishing_plugin.html

(1)创建插件项目(http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/creating_plugin_project.html)
这里写图片描述
(2)创建Action (http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/creating_an_action.html)
这里写图片描述
(3)获取当前项目、编辑器、文档对象

@Override
    public void actionPerformed(AnActionEvent e) {
        Project project = e.getProject();
        Editor editor = e.getData(CommonDataKeys.EDITOR);
        Document document = editor.getDocument();
        }

(4)显示提示信息

Messages.showMessageDialog("信息内容", "提示", Messages.getInformationIcon());

(5)获取鼠标选中文字

        SelectionModel selectionMode = editor.getSelectionModel();
        String selectText = selectionMode.getSelectedText();

(6)获取当前打开的文件

 PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);//e--->AnActionEvent 
 String content = psiFile.getViewProvider().getContents().toString();//文件内容

(7)文件写入信息

        Document document = editor.getDocument();
        WriteCommandAction.runWriteCommandAction(project, new Runnable() {
            @Override
            public void run() {
                document.insertString(xx, xxxxx);
            }
        });

(8)替换文字

        Document document = editor.getDocument();
        SelectionModel selectionModel = editor.getSelectionModel();
        int start = selectionModel.getSelectionStart();
        int end = selectionModel.getSelectionEnd();
        WriteCommandAction.runWriteCommandAction(project, () ->
                document.replaceString(start, end, "Replacement")
        );
        selectionModel.removeSelection();

(9)获取当前类

protected PsiClass getTargetClass(Editor editor, PsiFile file) {
    int offset = editor.getCaretModel().getOffset();
    PsiElement element = file.findElementAt(offset);
    if (element == null) {
        return null;
    } else {
        PsiClass target = (PsiClass) PsiTreeUtil.getParentOfType(element, PsiClass.class);
        return target instanceof SyntheticElement ? null : target;
    }
}

(10)获取ElementFactory

ElementFactory ElementFactory = JavaPsiFacade.getElementFactory(project);

(11)类操作

PsiClass psiClass = getTargetClass(editor, psiFile);
//添加字段  --- [其他方式可以更改createFieldFromText这里,还可以对方法、包都可以操作]
psiClass.add(JavaPsiFacade.getElementFactory(project).createFieldFromText("private Editext etxtUser;", psiClass));

ViewInject Plugin

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import org.apache.http.util.TextUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ViewInject extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        Project project = e.getProject();
        Editor editor = e.getData(CommonDataKeys.EDITOR);
        Document document = editor.getDocument();

        //获取选中文字
        SelectionModel selectionMode = editor.getSelectionModel();
        String selectText = selectionMode.getSelectedText();
        if (TextUtils.isEmpty(selectText)) {
            Messages.showMessageDialog("Select the layout name, such as: R.layout. Aty_main, and select aty_main", "提示", Messages.getInformationIcon());
            return;
        }

        //当前文件
        PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
        String currentContent = psiFile.getViewProvider().getContents().toString();
        String current[] = currentContent.split("\n");

        StringBuffer packageSb = new StringBuffer();
        packageSb.append("import android.widget.*;");
        packageSb.append("\n");
        packageSb.append("import com.android.annotation.ViewInject;");
        packageSb.append("\n");

        StringBuffer sbPackage = new StringBuffer();
        for (int i = 0; i < current.length; i++) {
            if (current[i].contains("import")) {
                break;
            } else {
                sbPackage.append(current[i] + "\n");
            }
        }

        WriteCommandAction.runWriteCommandAction(project, new Runnable() {
            @Override
            public void run() {
                document.insertString(sbPackage.length(), packageSb.toString());
            }
        });

        List<Map<String, String>> list = findViewIdByXmlName(project, selectText);

        StringBuffer fieldSb = new StringBuffer("\n");
        for (int i = 0; i < list.size(); i++) {
            Map<String, String> map = list.get(i);
            String id = map.get("id");
            String name = map.get("name");

            fieldSb.append("    @ViewInject(R.id." + id + ")");
            fieldSb.append("\n");
            fieldSb.append("    private " + name + " " + id + ";");
            fieldSb.append("\n");
        }

        StringBuffer sbTop = new StringBuffer();
        for (int i = 0; i < current.length; i++) {
            sbTop.append(current[i] + "\n");
            if (current[i].contains("{")) {
                break;
            }
        }

        WriteCommandAction.runWriteCommandAction(project, new Runnable() {
            @Override
            public void run() {
                document.insertString(sbTop.length() + packageSb.toString().length(), fieldSb.toString());
            }
        });

    }

    @Override
    public void update(AnActionEvent e) {
        super.update(e);
        //Get required data keys
        final Project project = e.getProject();
        final Editor editor = e.getData(CommonDataKeys.EDITOR);
        //Set visibility only in case of existing project and editor and if some text in the editor is selected
        e.getPresentation().setEnabled(project != null && editor != null);
    }

    /**
     * 全局搜索xml文件
     *
     * @param project 项目
     * @param xmlName xml名字
     * @return
     */
    private List<Map<String, String>> findViewIdByXmlName(Project project, String xmlName) {
        List<Map<String, String>> idList = new ArrayList<>();
        PsiFileSystemItem[] items = FilenameIndex.getFilesByName(project, xmlName + ".xml", GlobalSearchScope.allScope(project), false);
        if (items.length == 1) {
            XmlFile xmlFile = (XmlFile) PsiManager.getInstance(project).findFile(items[0].getVirtualFile());
            XmlTag tag = xmlFile.getRootTag();
            findViewByXmlTag(project, tag, idList);
        }
        return idList;
    }

    private List<Map<String, String>> findViewByXmlTag(Project project, XmlTag tag, List<Map<String, String>> idList) {
        putMap(project, tag, idList);
        XmlTag[] xmlTags = tag.getSubTags();
        for (int i = 0; i < xmlTags.length; i++) {
            XmlTag xmlTag = xmlTags[i];
            putMap(project, xmlTag, idList);
            XmlTag[] subTags = xmlTag.getSubTags();
            if (subTags.length != 0) {
                for (int j = 0; j < subTags.length; j++) {
                    findViewByXmlTag(project, subTags[j], idList);
                }
            }
        }
        return idList;
    }

    private void putMap(Project project, XmlTag xmlTag, List<Map<String, String>> idList) {
        if (xmlTag.getAttributeValue("android:id") != null) {
            Map<String, String> map = new HashMap<>();
            map.put("name", xmlTag.getName());
            map.put("id", xmlTag.getAttributeValue("android:id").replace("@+id/", ""));
            idList.add(map);
        }
        if (xmlTag.getName().equals("include") && xmlTag.getAttributeValue("layout") != null) {
            String name = xmlTag.getAttributeValue("layout").replace("@layout/", "");
            idList.addAll(findViewIdByXmlName(project, name));
        }
    }


}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值