【问题标题】:Custom Lint Rule to Check All Views in Layouts自定义 Lint 规则以检查布局中的所有视图
【发布时间】:2020-03-26 17:28:43
【问题描述】:

在我正在开发的应用程序中,所有布局文件中的所有视图都必须设置id。所以我正在尝试构建一个自定义 lint 规则来强制执行此操作。

通常,人们会使用XmlScanner 中的getApplicableElements() 方法,并为每个元素标记包含一个字符串列表。但是,我似乎无法找到一种方法来查看 XML 布局中的所有元素,这些元素是 View 的子类。

我尝试使用XmlScannerConstants.ALL,但是,它会查看每个 XML 文件中的每个元素。鉴于我们有几种其他类型的基于 XML 的资源,这是行不通的。

我的检查器类代码如下。有谁知道过滤getApplicableElements() 的好方法,所以它只查看子类View 的每个元素,仅此而已?

class IdDetector : ResourceXmlDetector() {

    companion object {

        private const val ISSUE_ID = "MissingId"
        private const val ISSUE_DESCRIPTION = "Missing required attribute 'id'"
        private const val ISSUE_EXPLANATION = "Identifiers are required on all views."

        val ISSUE = Issue.create(
            id = ISSUE_ID,
            briefDescription = ISSUE_DESCRIPTION,
            explanation = ISSUE_EXPLANATION,
            category = Category.A11Y,
            priority = 10,
            severity = Severity.FATAL,
            androidSpecific = true,
            implementation = Implementation(IdDetector::class.java, Scope.RESOURCE_FILE_SCOPE)
        )
    }

    override fun getApplicableElements(): Collection<String>? = XmlScannerConstants.ALL

    override fun visitElement(context: XmlContext, element: Element) {
        if (!element.hasAttributeNS("http://schemas.android.com/apk/res/android", "id")) {
            context.report(ISSUE, element, context.getLocation(element), ISSUE_DESCRIPTION)
        }
    }
}

【问题讨论】:

    标签: android lint


    【解决方案1】:

    appliesTo(@NonNull ResourceFolderType folderType) 方法可以帮助您实现这一目标。就您而言,我相信您只会对定位布局文件夹感兴趣。你的新检测器看起来像这样:

    class IdDetector : ResourceXmlDetector() {
    
        companion object {
    
            private const val ISSUE_ID = "MissingId"
            private const val ISSUE_DESCRIPTION = "Missing required attribute 'id'"
            private const val ISSUE_EXPLANATION = "Identifiers are required on all views."
    
            val ISSUE = Issue.create(
                id = ISSUE_ID,
                briefDescription = ISSUE_DESCRIPTION,
                explanation = ISSUE_EXPLANATION,
                category = Category.A11Y,
                priority = 10,
                severity = Severity.FATAL,
                androidSpecific = true,
                implementation = Implementation(IdDetector::class.java, Scope.RESOURCE_FILE_SCOPE)
            )
        }
    
        override fun appliesTo(folderType: ResourceFolderType): Boolean = ResourceFolderType.LAYOUT == folderType
    
        override fun getApplicableElements(): Collection<String>? = XmlScannerConstants.ALL
    
        override fun visitElement(context: XmlContext, element: Element) {
            if (!element.hasAttributeNS("http://schemas.android.com/apk/res/android", "id")) {
                context.report(ISSUE, element, context.getLocation(element), ISSUE_DESCRIPTION)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-25
      • 2014-10-30
      • 1970-01-01
      • 2011-01-25
      • 2021-03-17
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      相关资源
      最近更新 更多