├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable
│ │ │ │ ├── ic_person_black_24dp.xml
│ │ │ │ ├── ic_launcher_foreground.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── layout
│ │ │ │ └── activity_main.xml
│ │ ├── ic_launcher-web.png
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── redmadrobot
│ │ │ │ └── acronymavatarsample
│ │ │ │ └── MainActivity.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── redmadrobot
│ │ │ └── acronymavatarsample
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── redmadrobot
│ │ └── acronymavatarsample
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle.kts
├── acronymavatar
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ ├── values
│ │ │ ├── attrs.xml
│ │ │ └── default_colors.xml
│ │ └── drawable
│ │ │ └── default_placeholder.xml
│ │ └── kotlin
│ │ └── com
│ │ └── redmadrobot
│ │ └── acronymavatar
│ │ ├── AcronymDrawable.kt
│ │ └── AvatarView.kt
├── library.properties
├── proguard-rules.pro
└── build.gradle.kts
├── settings.gradle.kts
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── publish.gradle
├── detekt
├── detekt-baseline.xml
└── config.yml
├── gradle.properties
├── LICENSE
├── gradlew.bat
├── .gitignore
├── README.MD
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/acronymavatar/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/acronymavatar/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include (":acronymavatar")
2 | include (":app")
3 | rootProject.name = "AcronymAvatar"
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Sample
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedMadRobot/acronym-avatar/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/detekt/detekt-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/acronymavatar/library.properties:
--------------------------------------------------------------------------------
1 | lib_name=acronymavatar
2 | lib_description=Library to show avatars with acronyms.
3 | lib_vcs=https://github.com/RedMadRobot/acronym-avatar.git
4 | lib_issue_tracker=https://github.com/RedMadRobot/acronym-avatar/issues
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/acronymavatar/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_person_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/com/redmadrobot/acronymavatarsample/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.redmadrobot.acronymavatarsample
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/redmadrobot/acronymavatarsample/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.redmadrobot.acronymavatarsample
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.activity_main.*
6 |
7 | class MainActivity : AppCompatActivity() {
8 |
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | setContentView(R.layout.activity_main)
12 |
13 | dynamic_avatar.setText("User Avatar")
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/redmadrobot/acronymavatarsample/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.redmadrobot.acronymavatarsample
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.redmadrobot.acronymavatarsample", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.kts.kts.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/acronymavatar/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.kts.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | android.enableJetifier=true
10 | android.useAndroidX=true
11 | org.gradle.jvmargs=-Xmx2048m
12 | kotlin.code.style=official
13 | # When configured, Gradle will run in incubating parallel mode.
14 | # This option should only be used with decoupled projects. More details, visit
15 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
16 | # org.gradle.parallel=true
17 |
--------------------------------------------------------------------------------
/acronymavatar/src/main/res/values/default_colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | - #436ecd
4 | - #21ac94
5 | - #29ae5c
6 | - #a6c706
7 | - #ff7308
8 | - #ff7307
9 | - #f0592f
10 | - #cd4b7d
11 | - #9d5cb3
12 | - #675cb3
13 |
14 |
15 | - @color/leo
16 | - @color/nadja
17 | - @color/mark
18 | - @color/teresa
19 | - @color/georgina
20 | - @color/lucia
21 | - @color/jelena
22 | - @color/liby
23 | - @color/tibor
24 | - @color/sergio
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Redmadrobot
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id(Android.applicationPlugin)
3 |
4 | kotlin(Kotlin.androidPlugin)
5 | kotlin(Kotlin.androidExtensions)
6 | }
7 |
8 | android {
9 | compileSdkVersion(Android.compileSdk)
10 | buildToolsVersion(Android.buildTools)
11 |
12 | defaultConfig {
13 | applicationId = Android.DefaultConfig.applicationId
14 |
15 | minSdkVersion(Android.DefaultConfig.minSdk)
16 | targetSdkVersion(Android.DefaultConfig.targetSdk)
17 |
18 | versionCode = Android.DefaultConfig.versionCode
19 | versionName = Android.DefaultConfig.versionName
20 |
21 | testInstrumentationRunner = Android.DefaultConfig.instrumentationRunner
22 |
23 |
24 | buildTypes {
25 | getByName(Android.BuildTypes.release) {
26 | isMinifyEnabled = false
27 |
28 | proguardFiles(
29 | getDefaultProguardFile(Android.Proguard.androidOptimizedRules),
30 | Android.Proguard.projectRules
31 | )
32 | }
33 | }
34 |
35 | compileOptions {
36 | sourceCompatibility = JavaVersion.VERSION_1_8
37 | targetCompatibility = JavaVersion.VERSION_1_8
38 | }
39 |
40 | kotlinOptions {
41 | jvmTarget = "1.8"
42 | }
43 | }
44 | }
45 |
46 | dependencies {
47 | implementation(project(":acronymavatar"))
48 |
49 | implementation(Kotlin.stdLib)
50 | implementation(Dependencies.Common.appCompat)
51 | implementation(Dependencies.App.constraintlayout)
52 | }
53 |
--------------------------------------------------------------------------------
/acronymavatar/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id(Android.libraryPlugin)
3 | kotlin(Kotlin.androidPlugin)
4 | kotlin(Kotlin.androidExtensions)
5 | }
6 | apply(from = "../gradle/publish.gradle")
7 |
8 | android {
9 | compileSdkVersion(Android.compileSdk)
10 |
11 | defaultConfig {
12 | minSdkVersion(Android.DefaultConfig.minSdk)
13 | targetSdkVersion(Android.DefaultConfig.targetSdk)
14 | versionCode = Android.DefaultConfig.versionCode
15 | versionName = Android.DefaultConfig.versionName
16 |
17 | testInstrumentationRunner = Android.DefaultConfig.instrumentationRunner
18 |
19 | consumerProguardFile("consumer-rules.pro")
20 | }
21 |
22 | testOptions {
23 | unitTests.isReturnDefaultValues = true
24 | }
25 |
26 | buildTypes {
27 | getByName(Android.BuildTypes.release) {
28 | isMinifyEnabled = false
29 | proguardFiles(
30 | getDefaultProguardFile(Android.Proguard.androidOptimizedRules),
31 | Android.Proguard.projectRules
32 | )
33 | }
34 | }
35 |
36 | compileOptions {
37 | sourceCompatibility = JavaVersion.VERSION_1_8
38 | targetCompatibility = JavaVersion.VERSION_1_8
39 | }
40 |
41 | kotlinOptions {
42 | jvmTarget = "1.8"
43 | }
44 |
45 | for (sourceSet in sourceSets) {
46 | sourceSet.java.srcDirs("src/${sourceSet.name}/kotlin")
47 | }
48 |
49 | packagingOptions {
50 | exclude("META-INF/LICENSE*")
51 | }
52 | }
53 |
54 | dependencies {
55 | implementation(Kotlin.stdLib)
56 | implementation(Dependencies.Common.appCompat)
57 | }
58 |
--------------------------------------------------------------------------------
/acronymavatar/src/main/kotlin/com/redmadrobot/acronymavatar/AcronymDrawable.kt:
--------------------------------------------------------------------------------
1 | package com.redmadrobot.acronymavatar
2 |
3 | import android.graphics.*
4 | import android.graphics.drawable.Drawable
5 | import kotlin.math.min
6 |
7 |
8 | class AcronymDrawable(private val acronym: String, backgroundColor: Int, private val sizeFactor: Float) : Drawable() {
9 |
10 | private val paintBackground = Paint(Paint.ANTI_ALIAS_FLAG)
11 | private val paintText = Paint(Paint.ANTI_ALIAS_FLAG)
12 |
13 | private val boundsRect = RectF()
14 |
15 | init {
16 | setColors(backgroundColor)
17 | }
18 |
19 | override fun draw(canvas: Canvas) {
20 | boundsRect.set(bounds)
21 |
22 | paintText.textSize = bounds.height() / sizeFactor
23 |
24 | val radius = min(boundsRect.width(), boundsRect.height()) / 2
25 | canvas.drawCircle(boundsRect.centerX(), boundsRect.centerY(), radius, paintBackground)
26 |
27 | val yTextPosition = boundsRect.centerY() - paintText.ascent() / 2 - paintText.descent() / 2
28 | canvas.drawText(acronym, boundsRect.centerX(), yTextPosition, paintText)
29 | }
30 |
31 | override fun setAlpha(alpha: Int) {
32 | paintText.alpha = alpha
33 | paintBackground.alpha = alpha
34 | }
35 |
36 | override fun getOpacity() = PixelFormat.UNKNOWN
37 |
38 | override fun setColorFilter(colorFilter: ColorFilter?) {
39 | /* Not used */
40 | }
41 |
42 | private fun setColors(backgroundColor: Int, textColor: Int = 0xFFFFFFFF.toInt()) {
43 | paintBackground.color = backgroundColor
44 |
45 | with(paintText) {
46 | color = textColor
47 | textAlign = Paint.Align.CENTER
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/gradle/publish.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "maven-publish"
2 | apply plugin: "com.jfrog.bintray"
3 |
4 | def publishPropertiesFile = rootProject.file("gradle/publish.properties")
5 | def publishProperties = new Properties()
6 |
7 | if (publishPropertiesFile.canRead()) {
8 | publishProperties.load(new FileInputStream(publishPropertiesFile))
9 | }
10 |
11 | def libraryPropertiesFile = file("library.properties")
12 | def libraryProperties = new Properties()
13 |
14 | if (libraryPropertiesFile.canRead()) {
15 | libraryProperties.load(new FileInputStream(libraryPropertiesFile))
16 | }
17 |
18 | task androidSourcesJar(type: Jar) {
19 | archiveClassifier.set('sources')
20 | from android.sourceSets.main.java.srcDirs
21 | }
22 |
23 | afterEvaluate {
24 | publishing {
25 | publications {
26 | release(MavenPublication) {
27 | from components.release
28 |
29 | artifact androidSourcesJar
30 |
31 | groupId = publishProperties["group_id"]
32 | artifactId = libraryProperties["lib_name"]
33 | version = publishProperties["lib_version"]
34 | }
35 | }
36 | repositories {
37 | maven {
38 | name = "GitHubPackages"
39 |
40 | url = uri("https://maven.pkg.github.com/RedMadRobot/acronym-avatar")
41 | credentials {
42 | username = System.getenv("GITHUB_USER")
43 | password = System.getenv("GITHUB_TOKEN")
44 | }
45 | }
46 | }
47 | }
48 | }
49 |
50 | bintray {
51 | user = System.getenv("BINTRAY_USER")
52 | key = System.getenv("BINTRAY_KEY")
53 | publications = ["release"]
54 | override = true
55 |
56 | pkg {
57 | repo = publishProperties["repository"]
58 | name = libraryProperties["lib_name"]
59 | description = libraryProperties["lib_description"]
60 | userOrg = publishProperties["organization_id"]
61 | licenses = ["MIT"]
62 | vcsUrl = libraryProperties["lib_vcs"]
63 | issueTrackerUrl = libraryProperties["lib_issue_tracker"]
64 | publish = true
65 | publicDownloadNumbers = true
66 |
67 | version {
68 | name = publishProperties["lib_version"]
69 | released = new Date()
70 | vcsTag = publishProperties["lib_version"]
71 | }
72 |
73 | dryRun = false
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/libraries
5 | /.idea/modules.xml
6 | /.idea/workspace.xml
7 | .DS_Store
8 | /build
9 | /captures
10 | .externalNativeBuild
11 | ### Android template
12 | # Built application files
13 | *.apk
14 | *.ap_
15 |
16 | # Files for the ART/Dalvik VM
17 | *.dex
18 |
19 | # Java class files
20 | *.class
21 |
22 | # Generated files
23 | bin/
24 | gen/
25 | out/
26 |
27 | # Gradle files
28 | .gradle/
29 | build/
30 |
31 | # Local configuration file (sdk path, etc)
32 | local.properties
33 |
34 | # Proguard folder generated by Eclipse
35 | proguard/
36 |
37 | # Log Files
38 | *.log
39 |
40 | # Android Studio Navigation editor temp files
41 | .navigation/
42 |
43 | # Android Studio captures folder
44 | captures/
45 |
46 | # IntelliJ
47 | .idea/
48 |
49 | # Keystore files
50 | # Uncomment the following line if you do not want to check your keystore files in.
51 | #*.jks
52 |
53 | # External native build folder generated in Android Studio 2.2 and later
54 |
55 | # Google Services (e.g. APIs or Firebase)
56 | google-services.json
57 |
58 | # Freeline
59 | freeline.py
60 | freeline/
61 | freeline_project_description.json
62 |
63 | # fastlane
64 | fastlane/report.xml
65 | fastlane/Preview.html
66 | fastlane/screenshots
67 | fastlane/test_output
68 | fastlane/readme.md
69 | ### JetBrains template
70 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
71 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
72 |
73 | # User-specific stuff:
74 | .idea/**/workspace.xml
75 | .idea/**/tasks.xml
76 |
77 | # Sensitive or high-churn files:
78 | .idea/**/dataSources/
79 | .idea/**/dataSources.ids
80 | .idea/**/dataSources.local.xml
81 | .idea/**/sqlDataSources.xml
82 | .idea/**/dynamic.xml
83 | .idea/**/uiDesigner.xml
84 |
85 | # Gradle:
86 | .idea/**/gradle.xml
87 | .idea/**/libraries
88 |
89 | # CMake
90 | cmake-build-debug/
91 | cmake-build-release/
92 |
93 | # Mongo Explorer plugin:
94 | .idea/**/mongoSettings.xml
95 |
96 | ## File-based project format:
97 | *.iws
98 |
99 | ## Plugin-specific files:
100 |
101 | # IntelliJ
102 |
103 | # mpeltonen/sbt-idea plugin
104 | .idea_modules/
105 |
106 | # JIRA plugin
107 | atlassian-ide-plugin.xml
108 |
109 | # Cursive Clojure plugin
110 | .idea/replstate.xml
111 |
112 | # Crashlytics plugin (for Android Studio and IntelliJ)
113 | com_crashlytics_export_strings.xml
114 | crashlytics.properties
115 | crashlytics-build.properties
116 | fabric.properties
117 |
118 | gradle/publish.properties
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://bintray.com/redmadrobot-opensource/android/acronym-avatar/_latestVersion)
4 |
5 | # Description
6 |
7 | AcronymAvatar is a dumb simple library to show avatars with acronyms in your application. Should you like to show user's list in your messenger (yet another one...) or just create an unorthodox user profile? This library is the best choice for you.
8 |
9 |
10 |
11 | # Getting started
12 |
13 | Just include the library into your project as a Gradle dependency:
14 | ```Groovy
15 | implementation 'com.redmadrobot:acronym-avatar:2.0'
16 | ```
17 |
18 | Then add `AvatarView` into your XML layout:
19 | ```XML
20 |
24 | ```
25 |
26 | And pass full username to the `setText` method:
27 | ```Kotlin
28 | user_avatar.setText("Captain Nemo")
29 | ```
30 |
31 | That's all!
32 |
33 |
34 | # Capabilities
35 |
36 | * Setting text via XML and programmatically
37 | * Using custom placeholders (Drawables only!)
38 | * Configuring zoom out for the acronym
39 |
40 | ## Setting text via XML and programmatically
41 | Composing acronyms from text works like this: when you pass a single word through the `setText` method or through the `app:text` XML field, the library takes only first two symbols, and makes them an uppercased acronym. In case there are two or more words, the library takes first symbols from first and second words only, and makes them an uppercased acronym. For instance:
42 | * Captain -> CA
43 | * Captain Nemo -> CN
44 | * Nemo, my name forever more -> NM
45 |
46 | ## Using custom placeholders (Drawables only!)
47 | We like our default placeholder very much, but you won't probably want to use it in real-world applications ;) For this case we augmented our library with a custom placeholder feature. You can set it via XML as following:
48 | ```XML
49 |
54 | ```
55 |
56 | ## Configuring zoom out for the acronym
57 | The library is preconfigured to use optimal text zoom factor, but you can set your own value this way:
58 | ```XML
59 |
64 | ```
65 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
29 |
30 |
38 |
39 |
50 |
51 |
62 |
63 |
75 |
76 |
--------------------------------------------------------------------------------
/acronymavatar/src/main/kotlin/com/redmadrobot/acronymavatar/AvatarView.kt:
--------------------------------------------------------------------------------
1 | package com.redmadrobot.acronymavatar
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.graphics.drawable.Drawable
6 | import android.util.AttributeSet
7 | import android.util.DisplayMetrics
8 | import androidx.appcompat.widget.AppCompatImageView
9 | import androidx.core.content.ContextCompat
10 | import kotlin.properties.Delegates
11 |
12 |
13 | class AvatarView : AppCompatImageView {
14 | companion object {
15 | private const val DEFAULT_ZOOM_OUT = 2.3f
16 | private const val DEFAULT_WIDTH_DP = 40
17 | private const val DEFAULT_HEIGHT_DP = 40
18 | }
19 |
20 | private var rawText by Delegates.notNull()
21 | private var placeholder by Delegates.notNull()
22 | private var zoomOut by Delegates.notNull()
23 |
24 | private val colors = context.resources.getIntArray(R.array.avatar_colors_set)
25 |
26 | private val wordRegex = Regex("([a-zа-я]+)", RegexOption.IGNORE_CASE)
27 |
28 | constructor(context: Context) : super(context) {
29 | initView()
30 | }
31 |
32 | @JvmOverloads
33 | constructor(context: Context, attrs: AttributeSet, defStyle: Int = 0) : super(context, attrs, defStyle) {
34 | val additionalAttrs = context.obtainStyledAttributes(attrs, R.styleable.AvatarView, defStyle, 0)
35 |
36 | rawText = additionalAttrs.getString(R.styleable.AvatarView_text) ?: ""
37 | placeholder = additionalAttrs.getDrawable(R.styleable.AvatarView_placeholder) ?: getDefaultPlaceholder()!!
38 | zoomOut = additionalAttrs.getFloat(R.styleable.AvatarView_zoom_out, DEFAULT_ZOOM_OUT)
39 |
40 | additionalAttrs.recycle()
41 |
42 | initView()
43 | }
44 |
45 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
46 | setMeasuredDimension(calculateWidth(widthMeasureSpec), calculateHeight(heightMeasureSpec))
47 | }
48 |
49 | fun setText(value: String) {
50 | rawText = value
51 | initView()
52 | }
53 |
54 | private fun initView() {
55 | if (rawText.isEmpty() || wordRegex.findAll(rawText).count() == 0) {
56 | setImageDrawable(placeholder)
57 | } else {
58 | val acronym = getAcronym(rawText)
59 | val backgroundColor = colors[Math.abs(rawText.hashCode() % colors.size)]
60 |
61 | setImageDrawable(AcronymDrawable(acronym, backgroundColor, zoomOut))
62 | }
63 | }
64 |
65 | private fun getAcronym(text: String): String {
66 | val words = wordRegex.findAll(text)
67 |
68 | return when (words.count()) {
69 | 0 -> ""
70 | 1 -> words.first().value.take(2)
71 | else -> words.take(2).map { it.value.take(1) }.reduce { s1, s2 -> "$s1$s2" }
72 | }.toUpperCase()
73 | }
74 |
75 | private fun getDefaultPlaceholder() = ContextCompat.getDrawable(context, R.drawable.default_placeholder)
76 |
77 | private fun calculateWidth(widthMeasureSpec: Int) = getMeasurment(widthMeasureSpec, dp2px(DEFAULT_WIDTH_DP))
78 | private fun calculateHeight(heightMeasureSpec: Int) = getMeasurment(heightMeasureSpec, dp2px(DEFAULT_HEIGHT_DP))
79 |
80 | @SuppressLint("SwitchIntDef")
81 | private fun getMeasurment(measureSpec: Int, defaultSize: Int): Int {
82 | val specSize = MeasureSpec.getSize(measureSpec)
83 |
84 | return when(MeasureSpec.getMode(measureSpec)) {
85 | MeasureSpec.EXACTLY -> specSize
86 | else -> defaultSize
87 | }
88 | }
89 |
90 | private fun dp2px(dp: Int) = dp * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)
91 | }
92 |
--------------------------------------------------------------------------------
/acronymavatar/src/main/res/drawable/default_placeholder.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
24 |
30 |
36 |
42 |
48 |
54 |
60 |
66 |
72 |
78 |
84 |
90 |
91 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 |
14 |
20 |
26 |
32 |
38 |
44 |
50 |
56 |
62 |
68 |
74 |
80 |
86 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/detekt/config.yml:
--------------------------------------------------------------------------------
1 | build:
2 | maxIssues: 0
3 | excludeCorrectable: false
4 | weights:
5 | complexity: 2
6 | formatting: 1
7 | style: 1
8 | comments: 0.5
9 |
10 | config:
11 | validation: true
12 | # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
13 | excludes: ''
14 |
15 | processors:
16 | active: true
17 | exclude:
18 | - 'DetektProgressListener'
19 | # - 'FunctionCountProcessor'
20 | # - 'PropertyCountProcessor'
21 | # - 'ClassCountProcessor'
22 | # - 'PackageCountProcessor'
23 | # - 'KtFileCountProcessor'
24 |
25 | console-reports:
26 | active: true
27 | exclude:
28 | - 'ProjectStatisticsReport'
29 | - 'ComplexityReport'
30 | - 'NotificationReport'
31 | # - 'FindingsReport'
32 | - 'FileBasedFindingsReport'
33 |
34 | comments:
35 | active: true
36 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
37 | AbsentOrWrongFileLicense:
38 | active: false
39 | licenseTemplateFile: 'license.template'
40 | CommentOverPrivateFunction:
41 | active: false
42 | CommentOverPrivateProperty:
43 | active: false
44 | EndOfSentenceFormat:
45 | active: false
46 | endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
47 | UndocumentedPublicClass:
48 | active: false
49 | searchInNestedClass: true
50 | searchInInnerClass: true
51 | searchInInnerObject: true
52 | searchInInnerInterface: true
53 | UndocumentedPublicFunction:
54 | active: false
55 | UndocumentedPublicProperty:
56 | active: false
57 |
58 | complexity:
59 | active: true
60 | ComplexCondition:
61 | active: true
62 | threshold: 4
63 | ComplexInterface:
64 | active: false
65 | threshold: 10
66 | includeStaticDeclarations: false
67 | includePrivateDeclarations: false
68 | ComplexMethod:
69 | active: true
70 | threshold: 10
71 | ignoreSingleWhenExpression: false
72 | ignoreSimpleWhenEntries: false
73 | ignoreNestingFunctions: false
74 | nestingFunctions: [run, let, apply, with, also, use, forEach, isNotNull, ifNull]
75 | LabeledExpression:
76 | active: false
77 | ignoredLabels: []
78 | LargeClass:
79 | active: true
80 | threshold: 600
81 | LongMethod:
82 | active: true
83 | threshold: 60
84 | LongParameterList:
85 | active: true
86 | functionThreshold: 6
87 | constructorThreshold: 12
88 | ignoreDefaultParameters: true
89 | ignoreDataClasses: true
90 | ignoreAnnotated: [JsonClass]
91 | MethodOverloading:
92 | active: false
93 | threshold: 6
94 | NestedBlockDepth:
95 | active: true
96 | threshold: 4
97 | StringLiteralDuplication:
98 | active: true
99 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
100 | threshold: 3
101 | ignoreAnnotation: true
102 | excludeStringsWithLessThan5Characters: true
103 | ignoreStringsRegex: '$^'
104 | TooManyFunctions:
105 | active: true
106 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
107 | thresholdInFiles: 20
108 | thresholdInClasses: 20
109 | thresholdInInterfaces: 20
110 | thresholdInObjects: 20
111 | thresholdInEnums: 20
112 | ignoreDeprecated: false
113 | ignorePrivate: false
114 | ignoreOverridden: true
115 |
116 | coroutines:
117 | active: false
118 | GlobalCoroutineUsage:
119 | active: false
120 | RedundantSuspendModifier:
121 | active: false
122 |
123 | empty-blocks:
124 | active: true
125 | EmptyCatchBlock:
126 | active: true
127 | allowedExceptionNameRegex: '_|(ignore|expected).*'
128 | EmptyClassBlock:
129 | active: true
130 | EmptyDefaultConstructor:
131 | active: true
132 | EmptyDoWhileBlock:
133 | active: true
134 | EmptyElseBlock:
135 | active: true
136 | EmptyFinallyBlock:
137 | active: true
138 | EmptyForBlock:
139 | active: true
140 | EmptyFunctionBlock:
141 | active: true
142 | ignoreOverridden: false
143 | EmptyIfBlock:
144 | active: true
145 | EmptyInitBlock:
146 | active: true
147 | EmptyKtFile:
148 | active: true
149 | EmptySecondaryConstructor:
150 | active: true
151 | EmptyTryBlock:
152 | active: true
153 | EmptyWhenBlock:
154 | active: true
155 | EmptyWhileBlock:
156 | active: true
157 |
158 | exceptions:
159 | active: true
160 | ExceptionRaisedInUnexpectedLocation:
161 | active: true
162 | methodNames: [toString, hashCode, equals, finalize]
163 | InstanceOfCheckForException:
164 | active: true
165 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
166 | NotImplementedDeclaration:
167 | active: true
168 | PrintStackTrace:
169 | active: true
170 | RethrowCaughtException:
171 | active: true
172 | ReturnFromFinally:
173 | active: true
174 | ignoreLabeled: false
175 | SwallowedException:
176 | active: true
177 | ignoredExceptionTypes:
178 | - InterruptedException
179 | - NumberFormatException
180 | - ParseException
181 | - MalformedURLException
182 | allowedExceptionNameRegex: '_|(ignore|expected).*'
183 | ThrowingExceptionFromFinally:
184 | active: false
185 | ThrowingExceptionInMain:
186 | active: false
187 | ThrowingExceptionsWithoutMessageOrCause:
188 | active: true
189 | exceptions:
190 | - IllegalArgumentException
191 | - IllegalStateException
192 | - IOException'
193 | ThrowingNewInstanceOfSameException:
194 | active: false
195 | TooGenericExceptionCaught:
196 | active: true
197 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
198 | exceptionNames:
199 | - ArrayIndexOutOfBoundsException
200 | - Error
201 | - Exception
202 | - IllegalMonitorStateException
203 | - NullPointerException
204 | - IndexOutOfBoundsException
205 | - RuntimeException
206 | - Throwable
207 | allowedExceptionNameRegex: '_|(ignore|expected).*'
208 | TooGenericExceptionThrown:
209 | active: true
210 | exceptionNames:
211 | - Error
212 | - Exception
213 | - Throwable
214 | - RuntimeException
215 |
216 | formatting:
217 | active: true
218 | android: true
219 | autoCorrect: true
220 | AnnotationOnSeparateLine:
221 | active: false
222 | autoCorrect: true
223 | ChainWrapping:
224 | active: true
225 | autoCorrect: true
226 | CommentSpacing:
227 | active: true
228 | autoCorrect: true
229 | EnumEntryNameCase:
230 | active: false
231 | autoCorrect: true
232 | Filename:
233 | active: true
234 | FinalNewline:
235 | active: true
236 | autoCorrect: true
237 | insertFinalNewLine: true
238 | ImportOrdering:
239 | active: false
240 | autoCorrect: true
241 | Indentation:
242 | active: true
243 | autoCorrect: true
244 | indentSize: 4
245 | continuationIndentSize: 4
246 | MaximumLineLength:
247 | active: false # See style.MaxLineLength
248 | maxLineLength: 120
249 | ModifierOrdering:
250 | active: true
251 | autoCorrect: true
252 | MultiLineIfElse:
253 | active: true
254 | autoCorrect: true
255 | NoBlankLineBeforeRbrace:
256 | active: false
257 | autoCorrect: false
258 | NoConsecutiveBlankLines:
259 | active: true
260 | autoCorrect: true
261 | NoEmptyClassBody:
262 | active: true
263 | autoCorrect: true
264 | NoEmptyFirstLineInMethodBlock:
265 | active: false
266 | autoCorrect: true
267 | NoLineBreakAfterElse:
268 | active: true
269 | autoCorrect: true
270 | NoLineBreakBeforeAssignment:
271 | active: true
272 | autoCorrect: true
273 | NoMultipleSpaces:
274 | active: true
275 | autoCorrect: true
276 | NoSemicolons:
277 | active: true
278 | autoCorrect: true
279 | NoTrailingSpaces:
280 | active: true
281 | autoCorrect: true
282 | NoUnitReturn:
283 | active: true
284 | autoCorrect: true
285 | NoUnusedImports:
286 | active: true
287 | autoCorrect: true
288 | NoWildcardImports:
289 | active: false
290 | PackageName:
291 | active: false
292 | autoCorrect: true
293 | ParameterListWrapping:
294 | active: true
295 | autoCorrect: true
296 | indentSize: 4
297 | SpacingAroundColon:
298 | active: true
299 | autoCorrect: true
300 | SpacingAroundComma:
301 | active: true
302 | autoCorrect: true
303 | SpacingAroundCurly:
304 | active: true
305 | autoCorrect: true
306 | SpacingAroundDot:
307 | active: true
308 | autoCorrect: true
309 | SpacingAroundKeyword:
310 | active: true
311 | autoCorrect: true
312 | SpacingAroundOperators:
313 | active: true
314 | autoCorrect: true
315 | SpacingAroundParens:
316 | active: true
317 | autoCorrect: true
318 | SpacingAroundRangeOperator:
319 | active: true
320 | autoCorrect: true
321 | StringTemplate:
322 | active: true
323 | autoCorrect: true
324 |
325 | naming:
326 | active: true
327 | ClassNaming:
328 | active: true
329 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
330 | classPattern: '[A-Z][a-zA-Z0-9]*'
331 | ConstructorParameterNaming:
332 | active: true
333 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
334 | parameterPattern: '[a-z][A-Za-z0-9]*'
335 | privateParameterPattern: '[a-z][A-Za-z0-9]*'
336 | excludeClassPattern: '$^'
337 | ignoreOverridden: true
338 | EnumNaming:
339 | active: true
340 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
341 | enumEntryPattern: '[A-Z][_a-zA-Z0-9]*'
342 | ForbiddenClassName:
343 | active: false
344 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
345 | forbiddenName: []
346 | FunctionMaxLength:
347 | active: false
348 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
349 | maximumFunctionNameLength: 30
350 | FunctionMinLength:
351 | active: false
352 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
353 | minimumFunctionNameLength: 3
354 | FunctionNaming:
355 | active: true
356 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
357 | functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)'
358 | excludeClassPattern: '$^'
359 | ignoreOverridden: true
360 | FunctionParameterNaming:
361 | active: true
362 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
363 | parameterPattern: '[a-z][A-Za-z0-9]*'
364 | excludeClassPattern: '$^'
365 | ignoreOverridden: true
366 | InvalidPackageDeclaration:
367 | active: false
368 | rootPackage: ''
369 | MatchingDeclarationName:
370 | active: true
371 | mustBeFirst: true
372 | MemberNameEqualsClassName:
373 | active: true
374 | ignoreOverridden: true
375 | ObjectPropertyNaming:
376 | active: true
377 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
378 | constantPattern: '[A-Za-z][_A-Za-z0-9]*'
379 | propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
380 | privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
381 | PackageNaming:
382 | active: true
383 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
384 | packagePattern: '[a-z][_a-z0-9]*(\.[a-z][_a-z0-9]*)*'
385 | TopLevelPropertyNaming:
386 | active: true
387 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
388 | constantPattern: '[A-Z][_A-Z0-9]*'
389 | propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
390 | privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
391 | VariableMaxLength:
392 | active: false
393 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
394 | maximumVariableNameLength: 64
395 | VariableMinLength:
396 | active: false
397 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
398 | minimumVariableNameLength: 1
399 | VariableNaming:
400 | active: true
401 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
402 | variablePattern: '[a-z][A-Za-z0-9]*'
403 | privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
404 | excludeClassPattern: '$^'
405 | ignoreOverridden: true
406 |
407 | performance:
408 | active: true
409 | ArrayPrimitive:
410 | active: true
411 | ForEachOnRange:
412 | active: true
413 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
414 | SpreadOperator:
415 | active: true
416 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
417 | UnnecessaryTemporaryInstantiation:
418 | active: true
419 |
420 | potential-bugs:
421 | active: true
422 | Deprecation:
423 | active: true
424 | DuplicateCaseInWhenExpression:
425 | active: true
426 | EqualsAlwaysReturnsTrueOrFalse:
427 | active: true
428 | EqualsWithHashCodeExist:
429 | active: true
430 | ExplicitGarbageCollectionCall:
431 | active: true
432 | HasPlatformType:
433 | active: true
434 | ImplicitDefaultLocale:
435 | active: false
436 | InvalidRange:
437 | active: true
438 | IteratorHasNextCallsNextMethod:
439 | active: true
440 | IteratorNotThrowingNoSuchElementException:
441 | active: true
442 | LateinitUsage:
443 | active: false
444 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
445 | excludeAnnotatedProperties: []
446 | ignoreOnClassesPattern: ''
447 | MapGetWithNotNullAssertionOperator:
448 | active: true
449 | MissingWhenCase:
450 | active: true
451 | RedundantElseInWhen:
452 | active: true
453 | UnconditionalJumpStatementInLoop:
454 | active: true
455 | UnnecessaryNotNullOperator:
456 | active: true
457 | UnnecessarySafeCall:
458 | active: true
459 | UnreachableCode:
460 | active: true
461 | UnsafeCallOnNullableType:
462 | active: true
463 | UnsafeCast:
464 | active: false
465 | UselessPostfixExpression:
466 | active: true
467 | WrongEqualsTypeParameter:
468 | active: true
469 |
470 | style:
471 | active: true
472 | CollapsibleIfStatements:
473 | active: true
474 | DataClassContainsFunctions:
475 | active: false
476 | conversionFunctionPrefix: 'to'
477 | DataClassShouldBeImmutable:
478 | active: true
479 | EqualsNullCall:
480 | active: true
481 | EqualsOnSignatureLine:
482 | active: true
483 | ExplicitCollectionElementAccessMethod:
484 | active: true
485 | ExplicitItLambdaParameter:
486 | active: true
487 | # TODO: https://github.com/detekt/detekt/issues/950#issuecomment-401575701
488 | ExpressionBodySyntax:
489 | active: false
490 | includeLineWrapping: false
491 | ForbiddenComment:
492 | active: true
493 | values: ['FIXME' , 'STOPSHIP']
494 | allowedPatterns: ''
495 | ForbiddenImport:
496 | active: false
497 | imports: []
498 | forbiddenPatterns: ''
499 | ForbiddenMethodCall:
500 | active: false
501 | methods: []
502 | ForbiddenPublicDataClass:
503 | active: false
504 | ignorePackages: ['*.internal', '*.internal.*']
505 | ForbiddenVoid:
506 | active: true
507 | ignoreOverridden: false
508 | ignoreUsageInGenerics: false
509 | FunctionOnlyReturningConstant:
510 | active: true
511 | ignoreOverridableFunction: true
512 | excludedFunctions: 'describeContents'
513 | excludeAnnotatedFunction: ['dagger.Provides']
514 | LibraryCodeMustSpecifyReturnType:
515 | active: true
516 | LoopWithTooManyJumpStatements:
517 | active: true
518 | maxJumpCount: 1
519 | MagicNumber:
520 | active: true
521 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
522 | ignoreNumbers: ['-1', '0', '0.5', '1', '2']
523 | ignoreHashCodeFunction: true
524 | ignorePropertyDeclaration: false
525 | ignoreLocalVariableDeclaration: false
526 | ignoreConstantDeclaration: true
527 | ignoreCompanionObjectPropertyDeclaration: true
528 | ignoreAnnotation: false
529 | ignoreNamedArgument: true
530 | ignoreEnums: false
531 | ignoreRanges: false
532 | MandatoryBracesIfStatements:
533 | active: false # See formatting.MultiLineIfElse
534 | MandatoryBracesLoops:
535 | active: true
536 | MaxLineLength:
537 | active: true
538 | maxLineLength: 120
539 | excludePackageStatements: true
540 | excludeImportStatements: true
541 | excludeCommentStatements: false
542 | MayBeConst:
543 | active: true
544 | ModifierOrder:
545 | active: true
546 | NestedClassesVisibility:
547 | active: true
548 | NewLineAtEndOfFile:
549 | active: true
550 | NoTabs:
551 | active: true
552 | OptionalAbstractKeyword:
553 | active: true
554 | OptionalUnit:
555 | active: true
556 | OptionalWhenBraces:
557 | active: false
558 | PreferToOverPairSyntax:
559 | active: true
560 | ProtectedMemberInFinalClass:
561 | active: true
562 | RedundantExplicitType:
563 | active: true
564 | RedundantVisibilityModifierRule:
565 | active: true
566 | ReturnCount:
567 | active: true
568 | max: 2
569 | excludedFunctions: 'equals'
570 | excludeLabeled: false
571 | excludeReturnFromLambda: true
572 | excludeGuardClauses: false
573 | SafeCast:
574 | active: true
575 | SerialVersionUIDInSerializableClass:
576 | active: false
577 | SpacingBetweenPackageAndImports:
578 | active: false # See formatting.NoConsecutiveBlankLines
579 | ThrowsCount:
580 | active: true
581 | max: 2
582 | TrailingWhitespace:
583 | active: false # See formatting.NoTrailingWhitespace
584 | UnderscoresInNumericLiterals:
585 | active: true
586 | acceptableDecimalLength: 5
587 | UnnecessaryAbstractClass:
588 | active: true
589 | excludeAnnotatedClasses: ['dagger.Module']
590 | UnnecessaryAnnotationUseSiteTarget:
591 | active: true
592 | UnnecessaryApply:
593 | active: true
594 | UnnecessaryInheritance:
595 | active: true
596 | UnnecessaryLet:
597 | active: true
598 | UnnecessaryParentheses:
599 | active: true
600 | UntilInsteadOfRangeTo:
601 | active: true
602 | UnusedImports:
603 | active: false # See formatting.NoUnusedImports
604 | UnusedPrivateClass:
605 | active: true
606 | UnusedPrivateMember:
607 | active: true
608 | allowedNames: '(_|ignored|expected|serialVersionUID)'
609 | UseArrayLiteralsInAnnotations:
610 | active: true
611 | UseCheckOrError:
612 | active: true
613 | UseDataClass:
614 | active: false
615 | excludeAnnotatedClasses: []
616 | allowVars: false
617 | UseIfInsteadOfWhen:
618 | active: true
619 | UseRequire:
620 | active: true
621 | UselessCallOnNotNull:
622 | active: true
623 | UtilityClassWithPublicConstructor:
624 | active: true
625 | VarCouldBeVal:
626 | active: true
627 | WildcardImport:
628 | active: false
629 | excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.Test.kt', '**/*.Spec.kt', '**/*.Spek.kt']
630 | excludeImports: ['java.util.*', 'kotlinx.android.synthetic.*']
631 |
--------------------------------------------------------------------------------