Creating custom lint rules in Android enables you to enforce project-specific code standards and patterns. Learn how to implement custom Detectors, define Issues, and perform naming checks.
Setting Up a Custom Lint Detector
Start by creating a custom Detector class that extends Detector from the lint API:
class NamingConventionDetector : Detector() {
companion object {
val NAMING_ISSUE = Issue.create(
id = "NamingConvention",
briefDescription = "Class name should follow PascalCase",
explanation = "All public classes must follow PascalCase naming convention",
category = Category.CORRECTNESS,
priority = 6,
severity = Severity.WARNING
)
}
override fun getApplicableUastTypes(): List<Class<out UElement>> {
return listOf(UClass::class.java)
}
override fun createUastHandler(context: UastScannerContext): UElementHandler {
return object : UElementHandler() {
override fun visitClass(node: UClass) {
val className = node.name ?: return
if (!className[0].isUpperCase()) {
context.report(
NAMING_ISSUE,
node,
context.getNameLocation(node),
"Class '$className' should start with uppercase letter"
)
}
}
}
}
}
Registering the Detector
Create an IssueRegistry to register your detector:
class CustomIssueRegistry : IssueRegistry() {
override val issues: List<Issue>
get() = listOf(NamingConventionDetector.NAMING_ISSUE)
override val vendor: Vendor
get() = Vendor(
vendorName = "MyApp",
feedbackUrl = "https://github.com/myapp/issues"
)
}
Implementing Complex Naming Rules
For more advanced patterns, check method signatures and variable declarations:
if (node.isPublic && node.name?.matches(Regex("[a-z].*")) == true) {
context.report(NAMING_ISSUE, node, context.getNameLocation(node),
"Public class must use PascalCase naming")
}
Custom lint rules improve code consistency and catch architectural violations early. Test your rules thoroughly before deploying to CI/CD pipelines.
8 Android app templates on Gumroad
Top comments (0)