├── .idea
├── .name
├── vcs.xml
├── misc.xml
├── runConfigurations.xml
├── gradle.xml
├── jarRepositories.xml
└── codeStyles
│ └── Project.xml
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.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
│ │ │ ├── layout
│ │ │ │ └── activity_main.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── in
│ │ │ └── krharsh17
│ │ │ └── barview_sample
│ │ │ └── MainActivity.kt
│ ├── test
│ │ └── java
│ │ │ └── in
│ │ │ └── krharsh17
│ │ │ └── barview_sample
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── in
│ │ └── krharsh17
│ │ └── barview_sample
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── library
├── consumer-rules.pro
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ └── label_background.png
│ │ │ ├── values
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── attrs.xml
│ │ │ └── layout
│ │ │ │ └── alert_dialogue.xml
│ │ └── java
│ │ │ └── in
│ │ │ └── krharsh17
│ │ │ └── barview
│ │ │ ├── Constants.kt
│ │ │ ├── BarModel.kt
│ │ │ ├── Bar.kt
│ │ │ ├── BarView.kt
│ │ │ └── BarGroup.kt
│ ├── test
│ │ └── java
│ │ │ └── in
│ │ │ └── krharsh17
│ │ │ └── barview
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── in
│ │ └── krharsh17
│ │ └── barview
│ │ └── ExampleInstrumentedTest.kt
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── .settings
└── org.eclipse.buildship.core.prefs
├── demo-apk
└── app-debug.apk
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .dependabot
└── config.yml
├── .gitignore
├── .project
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
└── boring-cyborg.yml
├── .travis.yml
├── gradle.properties
├── PULL_REQUEST_TEMPLATE.md
├── updateApk.sh
├── gradlew.bat
├── CODE_OF_CONDUCT.md
├── README.md
├── CONTRIBUTING.md
└── gradlew
/.idea/.name:
--------------------------------------------------------------------------------
1 | BarView
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/consumer-rules.pro:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library'
2 | rootProject.name='BarView'
3 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/demo-apk/app-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/demo-apk/app-debug.apk
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BarView
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.dependabot/config.yml:
--------------------------------------------------------------------------------
1 | version: 1
2 | update_configs:
3 | - package_manager: "java:gradle"
4 | directory: "/"
5 | update_schedule: "weekly"
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/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/krharsh17/barview-android/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/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable/label_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/HEAD/library/src/main/res/drawable/label_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krharsh17/barview-android/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/krharsh17/barview-android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Dec 11 14:55:21 IST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
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 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #72FC26
7 | #FFEB3B
8 | #F720A1
9 | #18CEFC
10 |
11 |
--------------------------------------------------------------------------------
/library/src/test/java/in/krharsh17/barview/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | import org.junit.Assert
4 | import org.junit.Test
5 |
6 | /**
7 | * Example local unit test, which will execute on the development machine (host).
8 | *
9 | * @see [Testing documentation](http://d.android.com/tools/testing)
10 | */
11 | class ExampleUnitTest {
12 | @Test
13 | fun additionIsCorrect() {
14 | Assert.assertEquals(4, 2 + 2.toLong())
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/test/java/in/krharsh17/barview_sample/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package in.krharsh17.barview_sample;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void additionIsCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | barview-android
4 | Project barview-android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/library/src/main/java/in/krharsh17/barview/Constants.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | import `in`.krharsh17.barview.BarView
4 |
5 | interface Constants {
6 | companion object {
7 | const val LABEL_TEXT_COLOR = "#424242"
8 | const val VALUE_TEXT_COLOR = "#FFFFFF"
9 | const val RIPPLE_COLOR = "#EEEEEE"
10 | const val CHAR_ARRAY = "0123456789ABCDEF"
11 | val DEFAULT_INTRO_ANIMATION: Int = BarView.Companion.INTRO_ANIM_NONE
12 | const val DEFAULT_ANIMATION_DURATION = 1400
13 | }
14 | }
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BarView
3 | Highlight
4 | Fade
5 | Delete
6 | Remove Highlight?
7 | Remove Fade?
8 | Green
9 | Yellow
10 | Pink
11 | Blue
12 | Select a Highlight Color :
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/library/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/library/src/main/java/in/krharsh17/barview/BarModel.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | /**
4 | * This class is represents a BarView entity and contains all the attributes
5 | * required to instantiate a BarGroup
6 | */
7 | class BarModel
8 | /**
9 | * parameterized constructor
10 | *
11 | * @param label for the barGroup instance
12 | * @param value for approximating the length of Bargroup instance
13 | * @param color hex color value for the fill of barGroup instance
14 | * @param fillRatio for determining the percentage of the bar to be filled
15 | */(
16 | /**
17 | * getters and setters
18 | */
19 | var label: String, var value: String, var color: String, var fillRatio: Float, var elevation: Int, var radius: Int)
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/library/src/androidTest/java/in/krharsh17/barview/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | /**
10 | * Instrumented test, which will execute on an Android device.
11 | *
12 | * @see [Testing documentation](http://d.android.com/tools/testing)
13 | */
14 | @RunWith(AndroidJUnit4::class)
15 | class ExampleInstrumentedTest {
16 | @Test
17 | fun useAppContext() {
18 | // Context of the app under test.
19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
20 | Assert.assertEquals("in.krharsh17.barview.test", appContext.packageName)
21 | }
22 | }
--------------------------------------------------------------------------------
/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.
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 |
--------------------------------------------------------------------------------
/library/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.
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 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | sudo: required
3 | jdk: oraclejdk8
4 | android:
5 | components:
6 | - tools
7 | - platform-tools
8 | - build-tools-29.0.2
9 | - android-29
10 | - extra-google-google_play_services
11 | - extra-google-m2repository
12 | - extra-android-m2repository
13 | licenses:
14 | - android-sdk-license-.+
15 | before_install:
16 | - 'yes | sdkmanager "platforms;android-29"'
17 | - 'chmod +x ./gradlew'
18 | script:
19 | - 'echo "Hello! This is Travis"'
20 | - './gradlew build'
21 | before_cache:
22 | - 'rm -f $HOME/.gradle/caches/modules-2/modules-2.lock'
23 | - 'rm -fr $HOME/.gradle/caches/*/plugin-resolution/'
24 | after_success:
25 | - 'bash updateApk.sh'
26 | cache:
27 | directories:
28 | - $HOME/.gradle/caches/
29 | - $HOME/.gradle/wrapper/
30 | - $HOME/.android/build-cache
31 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/in/krharsh17/barview_sample/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package in.krharsh17.barview_sample;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 |
25 | assertEquals("in.krharsh17.barview_sample", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/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 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Issue that this pull request solves
2 |
3 | Fixes: # (issue number)
4 |
5 | ## Proposed changes
6 |
7 | Brief description of what is fixed or changed
8 |
9 | ## Types of changes
10 |
11 | _Put an `x` in the boxes that apply_
12 |
13 | - [ ] Bugfix (non-breaking change which fixes an issue)
14 | - [ ] New feature (non-breaking change which adds functionality)
15 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
16 | - [ ] Documentation update (Documentation content changed)
17 | - [ ] Other (please describe):
18 |
19 | ## Checklist
20 |
21 | _Put an `x` in the boxes that apply_
22 |
23 | - [ ] My code follows the style guidelines of this project
24 | - [ ] I have performed a self-review of my own code
25 | - [ ] I have commented my code, particularly in hard-to-understand areas
26 | - [ ] I have made corresponding changes to the documentation
27 | - [ ] My changes generate no new warnings
28 |
29 | ## Screenshots
30 |
31 | Please attach the screenshots of the changes made in case of change in user interface
32 |
33 | ## Other information
34 |
35 | Any other information that is important to this pull request
36 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion 29
6 | buildToolsVersion "29.0.2"
7 | defaultConfig {
8 | applicationId "in.krharsh17.barview_sample"
9 | minSdkVersion 21
10 | targetSdkVersion 29
11 | versionCode 1
12 | versionName "1.0"
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | }
22 |
23 | dependencies {
24 | implementation project (":library")
25 | implementation fileTree(dir: 'libs', include: ['*.jar'])
26 | implementation 'androidx.appcompat:appcompat:1.1.0'
27 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
28 | testImplementation 'junit:junit:4.12'
29 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
30 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
31 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
32 | implementation "androidx.core:core-ktx:+"
33 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
34 | }
35 | repositories {
36 | mavenCentral()
37 | }
38 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'com.github.dcendents.android-maven'
4 | group='com.github.krharsh17'
5 | android {
6 | compileSdkVersion 29
7 | buildToolsVersion "29.0.2"
8 |
9 |
10 | defaultConfig {
11 | minSdkVersion 21
12 | targetSdkVersion 29
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | consumerProguardFiles 'consumer-rules.pro'
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 |
27 | }
28 |
29 | dependencies {
30 | implementation fileTree(dir: 'libs', include: ['*.jar'])
31 |
32 | implementation 'androidx.appcompat:appcompat:1.1.0'
33 | testImplementation 'junit:junit:4.12'
34 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
35 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
36 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
37 | implementation "androidx.core:core-ktx:+"
38 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
39 | }
40 | repositories {
41 | mavenCentral()
42 | }
43 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/updateApk.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | export PUBLISH_BRANCH=${PUBLISH_BRANCH:-master}
5 | export DEVELOPMENT_BRANCH=${DEVELOPMENT_BRANCH:-develop}
6 |
7 | # Setup git
8 | git config --global user.email "noreply@travis.com"
9 | git config --global user.name "Travis CI"
10 |
11 | # Execute the following script only if it's merge to development or master branch
12 | if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_REPO_SLUG" != "krharsh17/barview-android" ] || ! [ "$TRAVIS_BRANCH" == "$DEVELOPMENT_BRANCH" -o "$TRAVIS_BRANCH" == "$PUBLISH_BRANCH" ]; then
13 | echo "We upload apk only for changes in Development or Master"
14 | exit 0
15 | fi
16 |
17 | # Generates app bundle
18 | ./gradlew bundleRelease
19 |
20 | # Clone the repository
21 | git clone --quiet --branch=apk "https://krharsh17:$GITHUB_KEY@github.com/krharsh17/barview-android" apk > /dev/null
22 |
23 | cd apk
24 |
25 | # Remove old files
26 | if [ "$TRAVIS_BRANCH" == "$PUBLISH_BRANCH" ]; then
27 | rm -rf barview-master*
28 | else
29 | rm -rf barview-dev*
30 | fi
31 |
32 | # Copy apk files
33 | find ../app/build/outputs -type f -name '*.apk' -exec cp -v {} . \;
34 |
35 | for file in app*; do
36 | if [ "$TRAVIS_BRANCH" == "$PUBLISH_BRANCH" ]; then
37 | mv "$file" barview-master-"${file:4}"
38 |
39 | elif [ "$TRAVIS_BRANCH" == "$DEVELOPMENT_BRANCH" ]; then
40 | mv "$file" barview-dev-"${file:4}"
41 | fi
42 | done
43 |
44 | git checkout --orphan temporary
45 |
46 | git add .
47 | git commit -m "Travis build pushed to [$TRAVIS_BRANCH]"
48 |
49 | # Delete current apk branch
50 | git branch -D apk
51 | # Rename current branch to apk
52 | git branch -m apk
53 |
54 | git push origin apk -f --quiet > /dev/null
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/in/krharsh17/barview_sample/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview_sample
2 |
3 | import `in`.krharsh17.barview.BarModel
4 | import `in`.krharsh17.barview.BarView
5 | import `in`.krharsh17.barview.BarView.Companion.randomColor
6 | import android.os.Bundle
7 | import androidx.appcompat.app.AppCompatActivity
8 | import java.util.*
9 |
10 | class MainActivity : AppCompatActivity() {
11 | var barView: BarView? = null
12 | var cornerRadius = 20 //in dp
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | setContentView(R.layout.activity_main)
16 | barView = findViewById(R.id.barview)
17 | val barModels: ArrayList = ArrayList()
18 | barModels.add(BarModel(
19 | "Samsung",
20 | "30.91",
21 | randomColor,
22 | 0.31f, 0, 0
23 | ))
24 | barModels.add(BarModel(
25 | "Apple",
26 | "25.89",
27 | randomColor,
28 | 1f, 5, 5
29 | ))
30 | barModels.add(BarModel(
31 | "Huawei",
32 | "10.98",
33 | randomColor,
34 | 0.11f, 8, 4
35 | ))
36 | barModels.add(BarModel(
37 | "Xiaomi",
38 | "7.8",
39 | randomColor,
40 | 0.07f, 12, 7
41 | ))
42 | barModels.add(BarModel(
43 | "Oppo",
44 | "4.31",
45 | randomColor,
46 | 0.04f, 7, 18
47 | ))
48 | barModels.add(BarModel(
49 | "Others",
50 | "20.11",
51 | randomColor,
52 | 0.20f, 8, 10
53 | ))
54 | barView!!.setData(barModels)
55 | barView!!.setCornerRadius(cornerRadius)
56 | barView!!.onBarClickListener = object : BarView.OnBarClickListener {
57 | override fun onBarClicked(pos: Int) {
58 | // Do Something
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
26 | * Trolling, insulting/derogatory comments, and personal or political attacks
27 | * Public or private harassment
28 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
29 | * Other conduct which could reasonably be considered inappropriate in a professional setting
30 |
31 | ## Our Responsibilities
32 |
33 | Project maintainers are responsible for clarifying the standards of acceptable
34 | behavior and are expected to take appropriate and fair corrective action in
35 | response to any instances of unacceptable behavior.
36 |
37 | Project maintainers have the right and responsibility to remove, edit, or
38 | reject comments, commits, code, wiki edits, issues, and other contributions
39 | that are not aligned to this Code of Conduct, or to ban temporarily or
40 | permanently any contributor for other behaviors that they deem inappropriate,
41 | threatening, offensive, or harmful.
42 |
43 | ## Scope
44 |
45 | This Code of Conduct applies both within project spaces and in public spaces
46 | when an individual is representing the project or its community. Examples of
47 | representing a project or community include using an official project e-mail
48 | address, posting via an official social media account, or acting as an appointed
49 | representative at an online or offline event. Representation of a project may be
50 | further defined and clarified by project maintainers.
51 |
52 | ## Enforcement
53 |
54 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
55 | reported by contacting the project team at kharsh39@gmail.com. All
56 | complaints will be reviewed and investigated and will result in a response that
57 | is deemed necessary and appropriate to the circumstances. The project team is
58 | obligated to maintain confidentiality with regard to the reporter of an incident.
59 | Further details of specific enforcement policies may be posted separately.
60 |
61 | Project maintainers who do not follow or enforce the Code of Conduct in good
62 | faith may face temporary or permanent repercussions as determined by other
63 | members of the project's leadership.
64 |
65 | ## Attribution
66 |
67 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
68 | available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)
69 |
70 | For answers to common questions about this code of conduct, see [faq](https://www.contributor-covenant.org/faq)
71 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/alert_dialogue.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
18 |
19 |
24 |
25 |
33 |
34 |
42 |
43 |
51 |
52 |
60 |
61 |
69 |
70 |
71 |
78 |
79 |
86 |
87 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BarView
2 |
3 | [](https://app.codacy.com/manual/kharsh39/barview-android?utm_source=github.com&utm_medium=referral&utm_content=krharsh17/barview-android&utm_campaign=Badge_Grade_Dashboard)
4 | [](https://travis-ci.com/krharsh17/barview-android)  
5 |
6 | [](https://jitpack.io/#krharsh17/barview-android)
7 |
8 |  
9 |
10 | BarView is a native android UI library that allows representation of data in bar graph with slick look and smooth animations. Currently the library is in a very early stage so it does not look very good 😋.
11 |
12 | This project has been selected for **[GirlScript Summer of Code 2020](https://www.gssoc.tech/)**. To begin contributing
13 | - Go through the [guidelines](https://github.com/krharsh17/barview-android/blob/develop/CONTRIBUTING.md)
14 | - Fork a copy of the project to your profile
15 | - Go through the issues and comment on one to get it assigned to yourself
16 | - Discuss on the [gitter](https://gitter.im/barview-android/community) or [slack](https://gssoc20.slack.com/) channel if you have any doubts
17 | - Make the changes in code and create a PR on the main repository
18 | - Ask for a review from a mentor/admin and wait until your code gets merged!
19 |
20 | ## Table of Contents
21 | - [Goal](#goal)
22 | - [Current Progress](#current-progress)
23 | - [Installation](#installation)
24 | - [Usage](#usage)
25 |
26 | ## Goal
27 |
28 | 
29 |
30 | ## Current Progress
31 |
32 | 
33 |
34 | ## Installation
35 |
36 | - In your project level build.gradle
37 | ```
38 | allprojects {
39 | repositories {
40 | ...
41 | maven { url 'https://jitpack.io' }
42 | }
43 | }
44 | ```
45 |
46 | - In your app level build.gradle
47 | ```
48 | dependencies {
49 | implementation 'com.github.krharsh17:barview-android:1.0'
50 | }
51 | ```
52 |
53 | ## Usage
54 |
55 | - XML
56 | ```
57 |
69 | ```
70 |
71 | - Important
72 | - All `app:` attributes are optional
73 | - The default values of `app:` attributes are mentioned above
74 | - `barGroupSpacing` & `barHeight` are in dp, while `valueTextSize` & `labelTextSize` are in sp
75 |
76 |
77 | - Java
78 | ```
79 |
80 | BarView barview = findViewById(R.id.barview);
81 |
82 | ArrayList barModels = new ArrayList<>();
83 |
84 | barModels.add(new BarModel(
85 | "label_text",
86 | "value_text",
87 | "color_hex",
88 | fill_ratio_float
89 | )
90 | );
91 |
92 | //Add more BarModels here..
93 |
94 | barview.setData(barModels);
95 |
96 | ```
97 |
98 | ## System Requirements
99 |
100 | - Git
101 | - Android Studio
102 |
103 | ## Learning Resources
104 |
105 | - https://developer.android.com/studio/install
106 | - https://try.github.io/
107 |
108 | The demo apk for the project is available [here](https://github.com/krharsh17/barview-android/blob/develop/demo-apk/app-debug.apk)
109 |
--------------------------------------------------------------------------------
/.github/boring-cyborg.yml:
--------------------------------------------------------------------------------
1 | ##### Labeler ##########################################################################################################
2 | # Enable "labeler" for your PR that would add labels to PRs based on the paths that are modified in the PR.
3 | labelPRBasedOnFilePath:
4 | # Add 'label1' to any changes within 'example' folder or any subfolders
5 | library-update:
6 | - library/**/*
7 |
8 | # Add 'label2' to any file changes within 'example2' folder
9 | # label2:
10 | # - example2/*
11 |
12 | # Complex: Add 'area/core' label to any change within the 'core' package
13 | sample-update:
14 | - app/src/*
15 | - app/src/**/*
16 |
17 | # Add 'test' label to any change to *.spec.js files within the source dir
18 |
19 | ##### Greetings ########################################################################################################
20 | # Comment to be posted to welcome users when they open their first PR
21 | firstPRWelcomeComment: >
22 | Thanks for opening this pull request! Please make sure you have checked out our contributing guidelines.
23 |
24 | # Comment to be posted to congratulate user on their first merged PR
25 | firstPRMergeComment: >
26 | Awesome work, congrats on your first merged pull request!
27 |
28 | # Comment to be posted to on first time issues
29 | firstIssueWelcomeComment: >
30 | Thanks for opening your first issue here! Be sure to follow the issue template!
31 |
32 | ###### IssueLink Adder #################################################################################################
33 | # Insert Issue (Jira/Github etc) link in PR description based on the Issue ID in PR title.
34 | # insertIssueLinkInPrDescription:
35 | # specify the placeholder for the issue link that should be present in the description
36 | # descriptionIssuePlaceholderRegexp: "^Issue link: (.*)$"
37 | # matchers:
38 | # you can have several matches - for different types of issues
39 | # only the first matching entry is replaced
40 | # jiraIssueMatch:
41 | # specify the regexp of issue id that you can find in the title of the PR
42 | # the match groups can be used to build the issue id (${1}, ${2}, etc.).
43 | # titleIssueIdRegexp: \[(AIRFLOW-[0-9]{4})\]
44 | # the issue link to be added. ${1}, ${2} ... are replaced with the match groups from the
45 | # title match (remember to use quotes)
46 | # descriptionIssueLink: "[${1}](https://issues.apache.org/jira/browse/${1}/)"
47 | # docOnlyIssueMatch:
48 | # titleIssueIdRegexp: \[(AIRFLOW-X{4})\]
49 | # descriptionIssueLink: "`Document only change`"
50 |
51 | ###### Title Validator #################################################################################################
52 | # Verifies if commit/PR titles match the regexp specified
53 | # verifyTitles:
54 | # Regular expression that should be matched by titles of commits or PR
55 | # titleRegexp: ^\[AIRFLOW-[0-9]{4}\].*$|^\[AIRFLOW-XXXX\].*$
56 | # If set to true, it will only check the commit in case there is a single commit.
57 | # In case of multiple commits it will check PR title.
58 | # This reflects the standard behaviour of Github that for `Squash & Merge` GitHub
59 | # takes the title of the squashed commit from PR title rather than from commit message ¯\_(ツ)_/¯
60 | # For single-commit PRs it takes the squashed commit message from the commit as expected.
61 | #
62 | # If set to false it will check all commit messages. This is useful when you do not squash commits at merge.
63 | # validateEitherPrOrSingleCommitTitle: true
64 |
65 | ###### PR/Branch Up-To-Date Checker ####################################################################################
66 | # Check if the branch is up to date with master when certain files are modified
67 | checkUpToDate:
68 | # File paths that you want to check for
69 | # In this example, it checks if the branch is up to date when alembic migrations are modified in the PR.
70 | # It helps avoid multiple heads in alembic migrations in a collaborative development project.
71 | - airflow/migrations/*
72 | - airflow/migrations/**/*
73 | - airflow/alembic.ini
--------------------------------------------------------------------------------
/library/src/main/java/in/krharsh17/barview/Bar.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | import android.R
4 | import android.animation.ValueAnimator
5 | import android.content.Context
6 | import android.content.res.ColorStateList
7 | import android.graphics.drawable.ColorDrawable
8 | import android.graphics.drawable.RippleDrawable
9 | import android.graphics.drawable.StateListDrawable
10 | import android.os.Build
11 | import android.view.View
12 | import android.view.animation.DecelerateInterpolator
13 |
14 | internal class Bar
15 | /**
16 | * It can be called by anyone directly from code to create a new instance of the view.
17 | * This constructor doesn’t have access to XML attributes, so you have to fill the parameters manually, using setters.
18 | *
19 | * @param context of the activity
20 | */
21 | (context: Context?) : View(context) {
22 | /**
23 | * this fuction sets up the relative width of the Bar with respect to the progress
24 | * value given to the BarModel.
25 | *
26 | * @param progress
27 | */
28 | //increaseWidth is used to give some extra width to bar so that this extra width is used by shadow
29 | fun setProgress(progress: Float, increaseWidth: Int, animationType: Int, animationDuration: Int) {
30 | val params = this.layoutParams
31 | if (animationType == BarView.INTRO_ANIM_EXPAND) {
32 | expand(this, animationDuration, Math.round(params.width * progress))
33 | } else if (animationType == BarView.INTRO_ANIM_NONE) {
34 | this.visibility = VISIBLE
35 | params.width = Math.round(params.width * progress) + increaseWidth
36 | this.layoutParams = params
37 | }
38 | invalidate()
39 | requestLayout()
40 | }
41 |
42 | override fun onAttachedToWindow() {
43 | super.onAttachedToWindow()
44 | this.isClickable = true
45 | this.isFocusable = true
46 | }
47 |
48 | companion object {
49 | /**
50 | * Sets a ripple drawable as the background of the bar
51 | * The background can display ripples on touch
52 | *
53 | * @param view - The view to set the background to
54 | * @param normalColor - Color when unpressed
55 | * @param touchColor - Color when pressed
56 | */
57 | fun setRippleDrawable(view: View, normalColor: Int, touchColor: Int) {
58 | try {
59 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
60 | val rippleDrawable = RippleDrawable(ColorStateList.valueOf(touchColor), view.background, null)
61 | view.background = rippleDrawable
62 | } else {
63 | val stateListDrawable = StateListDrawable()
64 | stateListDrawable.addState(intArrayOf(R.attr.state_pressed), ColorDrawable(touchColor))
65 | stateListDrawable.addState(intArrayOf(R.attr.state_focused), ColorDrawable(touchColor))
66 | stateListDrawable.addState(intArrayOf(), ColorDrawable(normalColor))
67 | view.background = stateListDrawable
68 | }
69 | } catch (e: Exception) {
70 | }
71 | }
72 |
73 | /**
74 | * Animator function for the 'expand' intro animation
75 | *
76 | * @param v
77 | * @param duration
78 | * @param targetWidth
79 | */
80 | fun expand(v: View, duration: Int, targetWidth: Int) {
81 |
82 | //int prevWidth = v.getWidth();
83 | val prevWidth = 0
84 | v.visibility = VISIBLE
85 | val valueAnimator = ValueAnimator.ofInt(prevWidth, targetWidth)
86 | valueAnimator.addUpdateListener { animation ->
87 | v.layoutParams.width = animation.animatedValue as Int
88 | //v.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
89 | v.requestLayout()
90 | }
91 | valueAnimator.interpolator = DecelerateInterpolator()
92 | valueAnimator.duration = duration.toLong()
93 | valueAnimator.start()
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | ### Submitting Feedback, Requests, and Bugs
4 |
5 | The process for submitting feedback, feature requests, and reporting bugs usually begins by discussion on [the community chat](https://gitter.im/barview-android/community) and, after initial clarification, through [GitHub issues](https://help.github.com/articles/about-issues/).
6 |
7 | ### Submitting Code and Documentation Changes
8 |
9 | The process for accepting changes operates by [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/) and has a few steps:
10 |
11 | 1. If you haven't submitted anything before, and you aren't (yet!) a collaborator on the project, **fork and clone** the repo:
12 |
13 | $ git clone https://github.com//barview-android.git
14 |
15 | 2. Create a **new branch** for the changes you want to work on. Choose a topic for your branch name that reflects the change:
16 |
17 | $ git checkout -b
18 |
19 | 3. **Create or modify the files** with your changes. If you want to show other people work that isn't ready to merge in, commit your changes then create a pull request (PR) with _WIP_ or _Work In Progress_ in the title.
20 |
21 | https://github.com/krharsh17/barview-android/pull/new/master
22 |
23 | 4. Once your changes are ready for final review, commit your changes then modify or **create your pull request (PR)**, assign as a reviewer or ping (using "`@`") a mentor/maintainer (someone able to merge in PRs) active on the project
24 |
25 | 5. Allow others sufficient **time for review and comments** before merging. We make use of GitHub's review feature to comment in-line on PRs when possible. There may be some fixes or adjustments you'll have to make based on feedback.
26 |
27 | 6. Once you have integrated comments, or waited for feedback, a maintainer should merge your changes in!
28 |
29 | ### Branching
30 |
31 | Our branching strategy is based on [this article](https://nvie.com/posts/a-successful-git-branching-model/) which I suggest you read.
32 |
33 | + **master** a history of releases, once merged to from develop and tagged we create a release on the play store & GitHub releases.
34 |
35 | + **develop** the actively worked on next release of the app, what we branch off of while working on new features and what we merge into upon feature completion
36 |
37 | + **feature/** or feature/\/ any branch under this directory is an actively developed feature, feature branches culminate in a PR, are merged and deleted.
38 | Typically a feature branch is off of develop and into develop but in rare scenarios if there is an issue in production a branch may be made off master to fix this issue, this type of feature branch must be merged to develop and master before being deleted.
39 | Branch names should be in the format **\-kebab-case-title**
40 |
41 | All branches should have distinct history and should be visually easy to follow, for this reason only perform merge commits when merging code either by PR or when synchronising.
42 |
43 | If you wish to rebase you should be following the [Golden Rule](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) and ahere to the advice in the heading [Aside: Rebase as cleanup is awesome in the coding lifecycle](https://www.atlassian.com/git/articles/git-team-workflows-merge-or-rebase).
44 |
45 | ### Building
46 |
47 | The BarView project is split into 2 modules
48 | 1. `app` - a sample app to test the barview library during development
49 | 1. `library` - the main library barview, which gets deployed to end user applications
50 |
51 | The default build is `debug`, with this variant you can use a debugger while developing. To install the application click the `run` button in Android Studio with the `app` configuration selected while you have a device connected.
52 |
53 | ### Linting
54 |
55 | PR should be linted properly locally. There is no system restriction applied for this, however, PRs will not be merged until they contain properly formatted code.
56 |
57 | ### Continous Integration
58 |
59 | All PRs will have all these tests run and a combined coverage report will be attached, if coverage is to go down the PR will be marked failed. On Travis CI the automated tests are run on an emulator. To
60 | learn more about the commands run on the CI please refer to [.travis.yml](https://github.com/krharsh17/barview-android/blob/develop/.travis.yml)
61 |
62 | ### Hope you have a wonderful experience contributing to the project 🎉
63 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/library/src/main/java/in/krharsh17/barview/BarView.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | import android.content.Context
4 | import android.graphics.Color
5 | import android.graphics.drawable.GradientDrawable
6 | import android.util.AttributeSet
7 | import android.util.Log
8 | import android.view.MotionEvent
9 | import android.view.View
10 | import android.view.ViewGroup
11 | import android.widget.LinearLayout
12 | import android.widget.ScrollView
13 | import java.util.*
14 |
15 | /**
16 | * This is the custom view which is the cumulation of various individual barGroups
17 | * extends from a ScrollView and implementing Constant interface
18 | */
19 | class BarView : ScrollView, Constants {
20 | private var containerLayout: LinearLayout
21 | private var mcontext: Context
22 | /**
23 | * Returns a reference to the attached Listener
24 | */
25 | /**
26 | * Attaches a onBarClickListener
27 | */
28 | var onBarClickListener: OnBarClickListener? = null
29 | private var barGroups: MutableList
30 | private var data: List? = null
31 | private var isDataPopulated = false
32 | var barMargin = 6
33 | var verticalSpacing = 48
34 | var barHeight = 20
35 | var labelFontSize = 18
36 | var valueFontSize = 9
37 | var valueTooltipCornerRadius = 0
38 |
39 | /**
40 | * setters and getters
41 | */
42 | var animationType: Int = Constants.Companion.DEFAULT_INTRO_ANIMATION
43 | var animationDuration: Int = Constants.Companion.DEFAULT_ANIMATION_DURATION
44 | private var backgroundColor: String? = null
45 | private var gradientStart: String? = null
46 | private var gradientEnd: String? = null
47 | private var gradientDirection: String? = null
48 | private var cornerRadius = 0
49 | var labelTextColor: String? = Constants.Companion.LABEL_TEXT_COLOR
50 | var valueTextColor: String? = Constants.Companion.VALUE_TEXT_COLOR
51 | private var LABEL_FONT: String? = null
52 | private var VALUE_FONT: String? = null
53 | var rippleColor: String? = Constants.Companion.RIPPLE_COLOR
54 |
55 | /**
56 | * parameterized constructors
57 | * It can be called by a anyone directly from code to create a new instance of the view.
58 | * This constructor doesn’t have access to XML attributes, so you have to fill the parameters manually, using setters.
59 | *
60 | * @param context of the activity
61 | */
62 | constructor(context: Context) : super(context) {
63 | this.mcontext = context
64 | barGroups = ArrayList()
65 | containerLayout = LinearLayout(context)
66 | containerLayout.layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
67 | containerLayout.orientation = LinearLayout.VERTICAL
68 | this.addView(containerLayout)
69 | }
70 |
71 | /**
72 | * parameterized constructors
73 | * This is the basic XML constructor. Without it, the layout inflater will crash.
74 | * The AttributeSet parameter contains all attribute values provided via XML.
75 | *
76 | * @param context is the context of the activity
77 | * @param attrs are the attribute values which are saved as an AttributeSet
78 | */
79 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
80 | this.mcontext = context
81 | barGroups = ArrayList()
82 | containerLayout = LinearLayout(context)
83 | containerLayout.layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
84 | containerLayout.orientation = LinearLayout.VERTICAL
85 | this.addView(containerLayout)
86 | if (attrs != null) {
87 | val a = context.obtainStyledAttributes(attrs,
88 | R.styleable.BarView, 0, 0)
89 | valueTooltipCornerRadius = a.getInteger(R.styleable.BarView_valueTooltipCornerRadius, valueTooltipCornerRadius)
90 | animationType = a.getInteger(R.styleable.BarView_introAnimationType, animationType)
91 | animationDuration = a.getInteger(R.styleable.BarView_introAnimationDuration, animationDuration)
92 | verticalSpacing = a.getInteger(R.styleable.BarView_barGroupSpacing, verticalSpacing)
93 | barHeight = a.getInteger(R.styleable.BarView_barHeight, barHeight)
94 | labelFontSize = a.getInteger(R.styleable.BarView_labelTextSize, labelFontSize)
95 | valueFontSize = a.getInteger(R.styleable.BarView_valueTextSize, valueFontSize)
96 | VALUE_FONT = a.getString(R.styleable.BarView_labelFont)
97 | LABEL_FONT = a.getString(R.styleable.BarView_labelFont)
98 | labelTextColor = a.getString(R.styleable.BarView_labelTextColor)
99 | valueTextColor = a.getString(R.styleable.BarView_valueTextColor)
100 | rippleColor = a.getString(R.styleable.BarView_rippleColor)
101 | backgroundColor = a.getString(R.styleable.BarView_backgroundColor)
102 | gradientStart = a.getString(R.styleable.BarView_gradientStart)
103 | gradientEnd = a.getString(R.styleable.BarView_gradientEnd)
104 | gradientDirection = a.getString(R.styleable.BarView_gradientDirection)
105 | if (labelTextColor == null) {
106 | labelTextColor = Constants.Companion.LABEL_TEXT_COLOR
107 | }
108 | if (valueTextColor == null) {
109 | valueTextColor = Constants.Companion.VALUE_TEXT_COLOR
110 | }
111 | if (rippleColor == null) {
112 | rippleColor = Constants.Companion.RIPPLE_COLOR
113 | }
114 | if (gradientDirection == null) {
115 | gradientDirection = "horizontal"
116 | }
117 | if (backgroundColor != null) {
118 | setBackgroundColor(backgroundColor)
119 | }
120 | if (gradientStart != null && gradientEnd != null) {
121 | setBackgroundGradient(gradientStart, gradientEnd, gradientDirection)
122 | }
123 | a.recycle()
124 | }
125 | }
126 |
127 | interface OnBarClickListener {
128 | fun onBarClicked(pos: Int)
129 | }
130 |
131 | fun setData(data: List?) {
132 | this.data = data
133 | if (animationType == INTRO_ANIM_NONE) {
134 | populateBarView(INTRO_ANIM_NONE, animationDuration)
135 | } else if (animationType == INTRO_ANIM_EXPAND) {
136 | populateBarView(INTRO_ANIM_EXPAND, animationDuration)
137 | }
138 | isDataPopulated = true
139 | }
140 |
141 | fun setData(data: List?, isAnimationEnabled: Boolean) {
142 | this.data = data
143 | if (isAnimationEnabled) {
144 | if (animationType == INTRO_ANIM_NONE) {
145 | populateBarView(INTRO_ANIM_NONE, animationDuration)
146 | } else if (animationType == INTRO_ANIM_EXPAND) {
147 | populateBarView(INTRO_ANIM_EXPAND, animationDuration)
148 | }
149 | } else {
150 | populateBarView(INTRO_ANIM_NONE, animationDuration)
151 | }
152 | }
153 |
154 | /**
155 | * This method iterates over various BarModels and adds a BarGroup for each
156 | * of the BarModels inside private member data
157 | */
158 | private fun populateBarView(animationType: Int, animationDuration: Int) {
159 | for (b in data!!) {
160 | addBar(b, animationType, animationDuration)
161 | }
162 | }
163 |
164 | /**
165 | * This method actuall instanciates BarGroups based on the BarModel passed in as
166 | * a param and cumulates it into barGroups.
167 | *
168 | * @param data is a BarModel that contains all the required to
169 | * construct a BarGroup instance.
170 | */
171 | private fun addBar(data: BarModel, animationType: Int, animationDuration: Int) {
172 | val barGroup = BarGroup(
173 | mcontext,
174 | data.label,
175 | data.color,
176 | data.value,
177 | data.fillRatio,
178 | animationType,
179 | animationDuration,
180 | barMargin,
181 | verticalSpacing,
182 | barHeight,
183 | labelFontSize,
184 | valueFontSize,
185 | labelTextColor,
186 | valueTextColor,
187 | rippleColor,
188 | cornerRadius,
189 | valueTooltipCornerRadius,
190 | LABEL_FONT,
191 | VALUE_FONT,
192 | data.elevation,
193 | data.radius
194 | )
195 | barGroup.setOnTouchListener(object : OnTouchListener {
196 | private val CLICK_ACTION_THRESHOLD = 200
197 | private var startX = 0f
198 | private var startY = 0f
199 | override fun onTouch(v: View, event: MotionEvent): Boolean {
200 | when (event.action) {
201 | MotionEvent.ACTION_DOWN -> {
202 | startX = event.x
203 | startY = event.y
204 | }
205 | MotionEvent.ACTION_UP -> {
206 | val endX = event.x
207 | val endY = event.y
208 | if (isAClick(startX, endX, startY, endY)) {
209 | Log.d("BarView", "you clicked!")
210 | onBarClickListener!!.onBarClicked(barGroups.indexOf(v))
211 | }
212 | }
213 | else -> Log.d("BarView", "onTouch:Unknown Event ")
214 | }
215 | return true
216 | }
217 |
218 | private fun isAClick(startX: Float, endX: Float, startY: Float, endY: Float): Boolean {
219 | val differenceX = Math.abs(startX - endX)
220 | val differenceY = Math.abs(startY - endY)
221 | return !(differenceX > CLICK_ACTION_THRESHOLD /* =5 */ || differenceY > CLICK_ACTION_THRESHOLD)
222 | }
223 | })
224 | barGroups.add(barGroup)
225 | containerLayout.addView(barGroup)
226 | invalidate()
227 | requestLayout()
228 | }
229 |
230 | fun setBackgroundColor(color: String?) {
231 | containerLayout.setBackgroundColor(Color.parseColor(color))
232 | }
233 |
234 | fun setBackgroundGradient(startColor: String?, endColor: String?, direction: String?) {
235 | val gd: GradientDrawable?
236 | gd = when (direction) {
237 | "horizontal" -> GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, intArrayOf(Color.parseColor(startColor), Color.parseColor(endColor)))
238 | "vertical" -> GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.parseColor(startColor), Color.parseColor(endColor)))
239 | else -> null
240 | }
241 | if (gd != null) {
242 | containerLayout.background = gd
243 | }
244 | }
245 |
246 | fun setCornerRadius(radius: Int) {
247 | cornerRadius = radius
248 | if (isDataPopulated) {
249 | containerLayout.removeAllViews()
250 | populateBarView(animationType, animationDuration)
251 | }
252 | }
253 |
254 | companion object {
255 | const val INTRO_ANIM_NONE = 0
256 | const val INTRO_ANIM_EXPAND = 1
257 |
258 | /**
259 | * This function returns a random color based on a constant {@value #CHAR_ARRAY}
260 | * It builds up the random hex value by randomly choosing between any of the 16
261 | * literals in the char array and appending them one after another
262 | *
263 | * @return a random color as a randomized hex val
264 | */
265 | @JvmStatic
266 | val randomColor: String
267 | get() {
268 | val letters: CharArray = Constants.Companion.CHAR_ARRAY.toCharArray()
269 | val color = StringBuilder("#")
270 | for (i in 0..5) {
271 | color.append(letters[Math.round(Math.floor(Math.random() * 16)).toInt()])
272 | }
273 | return color.toString()
274 | }
275 |
276 | /**
277 | * This function approximates the passed in color based on the tolerance value defined in
278 | * the method . It first deconstructs the passed in @ColorInt into its components and then
279 | * randomly adding or subtracting integers in the range of tolerance and then finally
280 | * constructing them all up together and returning a hex literal of the format #XXXXXX
281 | *
282 | * @param approximateColor is the color user wants the bar to be approximately like
283 | * @return
284 | */
285 | fun getRandomColor(approximateColor: Int): String {
286 | val tolerance = 5
287 | var blue = approximateColor and 0x000000ff
288 | var green = approximateColor and 0x0000ff00 shr 8
289 | var red = approximateColor and 0x00ff0000 shr 16
290 | blue = Math.min(Math.max(0, blue + getRandomNumberInRange(-tolerance, tolerance)), 255)
291 | green = Math.min(Math.max(0, green + getRandomNumberInRange(-tolerance, tolerance)), 255)
292 | red = Math.min(Math.max(0, red + getRandomNumberInRange(-tolerance, tolerance)), 255)
293 | val newApproximateColor = -0x1000000 or (red shl 16) or (green shl 8) or blue
294 | val approximateColorHexLiteral = Integer.toHexString(newApproximateColor)
295 | return "#" + approximateColorHexLiteral.substring(2)
296 | }
297 |
298 | /**
299 | * Helper function returns any random integer between the specified bounds
300 | * both inclusive
301 | *
302 | * @param min variance the user wants in the approximate color
303 | * @param max variance the user wants in the approximate color
304 | * @return
305 | */
306 | private fun getRandomNumberInRange(min: Int, max: Int): Int {
307 | val r = Random()
308 | return r.nextInt(max - min + 1) + min
309 | }
310 | }
311 | }
--------------------------------------------------------------------------------
/library/src/main/java/in/krharsh17/barview/BarGroup.kt:
--------------------------------------------------------------------------------
1 | package `in`.krharsh17.barview
2 |
3 | import android.animation.ValueAnimator
4 | import android.content.Context
5 | import android.graphics.*
6 | import android.graphics.drawable.*
7 | import android.graphics.drawable.shapes.RoundRectShape
8 | import android.util.TypedValue
9 | import android.view.Gravity
10 | import android.view.LayoutInflater
11 | import android.view.View
12 | import android.view.ViewGroup
13 | import android.view.animation.Animation
14 | import android.view.animation.DecelerateInterpolator
15 | import android.view.animation.Transformation
16 | import android.widget.*
17 | import androidx.appcompat.app.AlertDialog
18 | import androidx.constraintlayout.widget.ConstraintLayout
19 | import androidx.constraintlayout.widget.ConstraintSet
20 | import androidx.constraintlayout.widget.Constraints
21 | import java.util.*
22 |
23 | /**
24 | * this class is the custom view which appears as bars in the BarView
25 | * extends ConstraintLayout and implements Constants interface
26 | */
27 | internal class BarGroup : ConstraintLayout, Constants {
28 | private var mcontext: Context
29 | private var label: TextView
30 | private var initial: View
31 | private var bar: Bar
32 | private var value: TextView
33 | private var increaseHeight = 0f
34 | private var increaseWidth = 0
35 | private var labelText: String?
36 | private var color: String?
37 | private var valueText: String?
38 | private var progress: Float
39 | var elevation = 0
40 | var radius = 0
41 | var numberOfLayers = 0
42 | private var animationType = 0
43 | private var animationDuration: Int = Constants.Companion.DEFAULT_ANIMATION_DURATION
44 | private var BAR_MARGIN = 6
45 | private var VERTICAL_SPACING = 48
46 | private var BAR_HEIGHT = 20
47 | private var LABEL_FONT_SIZE = 18
48 | private var VALUE_FONT_SIZE = 9
49 | private var labelTextColor: String? = Constants.Companion.LABEL_TEXT_COLOR
50 | private var valueTextColor: String? = Constants.Companion.VALUE_TEXT_COLOR
51 | private var VALUE_FONT: String? = null
52 | private var LABEL_FONT: String? = null
53 | private var rippleColor: String? = Constants.Companion.RIPPLE_COLOR
54 | private var CORNER_RADIUS = 0
55 | private var VALUE_TOOLTIP_CORNER_RADIUS = 0
56 |
57 | /**
58 | * one bar has different drawable stacked together with same solid color but different alpha value
59 | * this array of string defined different alpha value from 0 to 1
60 | * we will use maximum of 18 layers for shadow
61 | * numbers of layers can very depending on elevation value
62 | */
63 | var alphaSet = arrayOf(
64 | "#00",
65 | "#02",
66 | "#04",
67 | "#06",
68 | "#08",
69 | "#10",
70 | "#12",
71 | "#14",
72 | "#16",
73 | "#18",
74 | "#20",
75 | "#22",
76 | "#24",
77 | "#26",
78 | "#28",
79 | "#30",
80 | "#32",
81 | "#35",
82 | "#"
83 | )
84 |
85 | /**
86 | * parameterized constructor
87 | *
88 | * @param context of the activity
89 | * @param labelText for the barGroup instance
90 | * @param color hex color value for the fill of barGroup instance
91 | * @param valueText for approximating the length of Bargroup instance
92 | * @param progress marking the progress of the bar
93 | */
94 | constructor(context: Context, labelText: String?, color: String?, valueText: String?, progress: Float) : super(context) {
95 | this.mcontext = context
96 | this.labelText = labelText
97 | this.color = color
98 | this.valueText = valueText
99 | this.progress = progress
100 | label = TextView(context)
101 | initial = View(context)
102 | bar = Bar(context)
103 | bar.visibility = View.GONE
104 | value = TextView(context)
105 | }
106 |
107 | /**
108 | * parameterized constructor
109 | *
110 | * @param context of the activity
111 | * @param labelText for the barGroup instance
112 | * @param color hex color value for the fill of barGroup instance
113 | * @param valueText for approximating the length of Bargroup instance
114 | * @param progress marking the progress of the bar
115 | * self explanatory constants
116 | * @param BAR_MARGIN
117 | * @param VERTICAL_SPACING
118 | * @param BAR_HEIGHT
119 | * @param LABEL_FONT_SIZE
120 | * @param VALUE_FONT_SIZE
121 | * @param labelTextColor
122 | * @param VALUE_TEXT_COLOR
123 | * @param RIPPLE_COLOUR
124 | * @param CORNER_RADIUS
125 | * @param LABEL_FONT
126 | * @param VALUE_FONT
127 | */
128 | constructor(
129 | context: Context,
130 | labelText: String?,
131 | color: String?,
132 | valueText: String?,
133 | progress: Float,
134 | animationType: Int,
135 | animationDuration: Int,
136 | BAR_MARGIN: Int,
137 | VERTICAL_SPACING: Int,
138 | BAR_HEIGHT: Int,
139 | LABEL_FONT_SIZE: Int,
140 | VALUE_FONT_SIZE: Int,
141 | labelTextColor: String?,
142 | VALUE_TEXT_COLOR: String?,
143 | RIPPLE_COLOUR: String?,
144 | CORNER_RADIUS: Int,
145 | VALUE_TOOLTIP_CORNER_RADIUS: Int,
146 | LABEL_FONT: String?,
147 | VALUE_FONT: String?,
148 | elevation: Int,
149 | radius: Int) : super(context) {
150 | this.mcontext = context
151 | this.labelText = labelText
152 | this.color = color
153 | this.valueText = valueText
154 | this.progress = progress
155 | this.animationType = animationType
156 | this.animationDuration = animationDuration
157 | this.BAR_MARGIN = BAR_MARGIN
158 | this.VERTICAL_SPACING = VERTICAL_SPACING
159 | this.BAR_HEIGHT = BAR_HEIGHT
160 | this.LABEL_FONT_SIZE = LABEL_FONT_SIZE
161 | this.VALUE_FONT_SIZE = VALUE_FONT_SIZE
162 | this.labelTextColor = labelTextColor
163 | valueTextColor = VALUE_TEXT_COLOR
164 | rippleColor = RIPPLE_COLOUR
165 | this.LABEL_FONT = LABEL_FONT
166 | this.VALUE_FONT = VALUE_FONT
167 | this.CORNER_RADIUS = CORNER_RADIUS
168 | this.VALUE_TOOLTIP_CORNER_RADIUS = VALUE_TOOLTIP_CORNER_RADIUS
169 | label = TextView(context)
170 | initial = View(context)
171 | bar = Bar(context)
172 | value = TextView(context)
173 | this.elevation = elevation
174 | this.radius = radius
175 | }
176 |
177 | override fun onAttachedToWindow() {
178 | super.onAttachedToWindow()
179 | label.id = View.generateViewId()
180 | initial.id = View.generateViewId()
181 | bar.id = View.generateViewId()
182 | value.id = View.generateViewId()
183 | if (elevation > 0) {
184 | when (elevation) {
185 | 1, 2, 3 -> numberOfLayers = 5
186 | 4 -> numberOfLayers = 6
187 | 5 -> numberOfLayers = 7
188 | 6 -> numberOfLayers = 8
189 | 7 -> numberOfLayers = 9
190 | 8 -> numberOfLayers = 10
191 | 9 -> numberOfLayers = 11
192 | 10 -> numberOfLayers = 12
193 | 11, 12, 13 -> numberOfLayers = 14
194 | 14, 15, 16 -> numberOfLayers = 16
195 | else -> numberOfLayers = 18
196 | }
197 | }
198 | setupLabel()
199 | setupInitial()
200 | setupBar()
201 | setupValue()
202 | applyConstraints()
203 | }
204 |
205 | /**
206 | * Initializer function for the label segment
207 | */
208 | private fun setupLabel() {
209 | val labelParams: LayoutParams = Constraints.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
210 | labelParams.setMargins(
211 | dp(8f),
212 | dp(VERTICAL_SPACING / 2.toFloat()),
213 | dp(8f),
214 | dp(VERTICAL_SPACING / 2.toFloat())
215 | )
216 | label.text = parseLabel(labelText)
217 | label.setTextColor(Color.parseColor(labelTextColor))
218 | label.setTextSize(TypedValue.COMPLEX_UNIT_SP, LABEL_FONT_SIZE.toFloat())
219 | if (LABEL_FONT != null) {
220 | label.typeface = Typeface.createFromAsset(mcontext.assets, LABEL_FONT)
221 | }
222 | label.layoutParams = labelParams
223 | label.textAlignment = View.TEXT_ALIGNMENT_CENTER
224 | label.gravity = Gravity.CENTER_VERTICAL
225 | this.addView(label)
226 | }
227 |
228 | /**
229 | * Initializer function for the initial block
230 | */
231 | fun setupInitial() {
232 | val layers = arrayOfNulls(numberOfLayers + 1)
233 | setLayerForInitial(numberOfLayers, layers)
234 | var initialParams = LayoutParams(dp(12f) + increaseWidth, (dp(BAR_HEIGHT.toFloat()) * increaseHeight).toInt())
235 | initialParams.rightMargin = dp(12f)
236 | initial.layoutParams = initialParams
237 | val splash_test = LayerDrawable(layers)
238 | initial.background = splash_test
239 | initial.visibility = View.GONE
240 | Bar.setRippleDrawable(initial, Color.parseColor(color), Color.parseColor(rippleColor))
241 | initial.isClickable = true
242 | initial.isFocusable = true
243 | this.addView(initial)
244 | if (animationType == BarView.Companion.INTRO_ANIM_NONE) {
245 | initial.visibility = View.VISIBLE
246 | initialParams = LayoutParams(dp(12f), dp(BAR_HEIGHT.toFloat()))
247 | initialParams.rightMargin = dp(12f)
248 | initial.layoutParams = initialParams
249 | } else if (animationType == BarView.Companion.INTRO_ANIM_EXPAND) {
250 | val screen_width = Math.round(160 * mcontext.resources.displayMetrics.widthPixels / mcontext.resources.displayMetrics.xdpi)
251 | initialParams = LayoutParams(screen_width, dp(BAR_HEIGHT.toFloat()))
252 | initialParams.rightMargin = dp(12f)
253 | initial.layoutParams = initialParams
254 | expand(initial, animationDuration, dp(12f))
255 | }
256 | }
257 |
258 | /**
259 | * Initializer function for the main bar
260 | */
261 | fun setupBar() {
262 | val layers = arrayOfNulls(numberOfLayers + 1)
263 | setLayerForBar(numberOfLayers, layers)
264 | val screen_width = Math.round(160 * mcontext.resources.displayMetrics.widthPixels / mcontext.resources.displayMetrics.xdpi)
265 | bar.layoutParams = LinearLayout.LayoutParams(
266 | screen_width, (dp(BAR_HEIGHT.toFloat()) * increaseHeight).toInt()
267 | )
268 | val splash_test = LayerDrawable(layers)
269 | bar.background = splash_test
270 | this.addView(bar)
271 | bar.visibility = View.GONE
272 | Bar.setRippleDrawable(bar, Color.parseColor(color), Color.parseColor(rippleColor))
273 | bar.setProgress(progress, increaseWidth, animationType, animationDuration)
274 | bar.setOnLongClickListener {
275 | addOptions()
276 | true
277 | }
278 | }
279 |
280 | /**
281 | * Initializer function for the value tooltip. By default the corner radius of tooltips is zero
282 | * and if user specifies a value for corner radius then the changes ar applied in the tooltips.
283 | *
284 | *
285 | */
286 | private fun setupValue() {
287 | value.text = valueText
288 | //value.setBackground(context.getResources().getDrawable(R.drawable.label_background));
289 | val bitmap = Bitmap.createBitmap(
290 | 110, // Width
291 | 60, // Height
292 | Bitmap.Config.ARGB_8888 // Config
293 | )
294 | val canvas = Canvas(bitmap)
295 | canvas.drawColor(Color.WHITE)
296 | val paint = Paint()
297 | paint.style = Paint.Style.FILL
298 | paint.color = Color.BLACK
299 | paint.isAntiAlias = true
300 | val offset = 5
301 | val rectF = RectF(
302 | offset.toFloat(), // left
303 | offset.toFloat(), // top
304 | (canvas.width - offset).toFloat(), // right
305 | (canvas.height - offset).toFloat() // bottom
306 | )
307 | val cornersRadius = VALUE_TOOLTIP_CORNER_RADIUS
308 | canvas.drawRoundRect(
309 | rectF, // rect
310 | cornersRadius.toFloat(), // rx
311 | cornersRadius.toFloat(), // ry
312 | paint // Paint
313 | ) // method to draw rectangular tooltip with specified corner radius
314 | val d: Drawable = BitmapDrawable(resources, bitmap) // conversion of bitmap into drawable
315 | value.background = d
316 | value.rotation = 90f
317 | value.gravity = Gravity.CENTER
318 | value.setPadding(0, dp(8f), 0, dp(8f))
319 | value.setTextColor(Color.parseColor(valueTextColor))
320 | value.setTextSize(TypedValue.COMPLEX_UNIT_SP, VALUE_FONT_SIZE.toFloat())
321 | value.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
322 | if (VALUE_FONT != null) {
323 | val tf = get(VALUE_FONT!!, mcontext)
324 | value.typeface = tf
325 | }
326 | value.layoutParams = LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
327 | value.isClickable = true
328 | value.isFocusable = true
329 | Bar.setRippleDrawable(value, Color.parseColor(color), Color.parseColor(rippleColor))
330 | this.addView(value)
331 | }
332 |
333 | /**
334 | * Sets constraints for all pieces of a BarGroup instance
335 | */
336 | private fun applyConstraints() {
337 | val constraintSet = ConstraintSet()
338 | constraintSet.clone(this)
339 | constraintSet.setHorizontalBias(initial.id, 0.30f)
340 | constraintSet.connect(initial.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 0)
341 | constraintSet.connect(initial.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0)
342 | constraintSet.connect(initial.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, dp(BAR_MARGIN.toFloat()))
343 | constraintSet.connect(initial.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, dp(BAR_MARGIN.toFloat()))
344 | constraintSet.connect(bar.id, ConstraintSet.START, initial.id, ConstraintSet.END, dp(BAR_MARGIN.toFloat()))
345 | constraintSet.connect(bar.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
346 | constraintSet.connect(bar.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
347 | constraintSet.connect(value.id, ConstraintSet.START, bar.id, ConstraintSet.END, dp(BAR_MARGIN.toFloat()))
348 | constraintSet.connect(value.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
349 | constraintSet.connect(value.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
350 | constraintSet.connect(label.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 0)
351 | constraintSet.connect(label.id, ConstraintSet.END, initial.id, ConstraintSet.END, 0)
352 | constraintSet.connect(label.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
353 | constraintSet.connect(label.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
354 | constraintSet.applyTo(this)
355 | }
356 |
357 | /**
358 | * Converts density independent pixel units (dp) to pixel units (px)
359 | *
360 | * @param dp
361 | */
362 | private fun dp(dp: Float): Int {
363 | return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mcontext.resources.displayMetrics))
364 | }
365 |
366 | /**
367 | * elevation
368 | * Function for creating drawable of with solid color and with specific alpha
369 | *
370 | * @param color
371 | * @param currentLayer
372 | * @param totalLayer
373 | * @param radius
374 | */
375 | fun getRoundRect(color: String, currentLayer: Int, totalLayer: Int, radius: Int): Drawable {
376 | var localRadius = radius
377 | var leftTopPadding = 1
378 | if (currentLayer % 3 == 0) {
379 | leftTopPadding = 2
380 | }
381 | val rightPadding = 3
382 | val bottomPadding = 3
383 | var shadowalpha: String? = null
384 | val increment = 16 / (totalLayer - 2)
385 | var layernumber = 0
386 | if (radius < 0) {
387 | localRadius = 0
388 | }
389 | if (radius > 20) {
390 | localRadius = 20
391 | }
392 | if (currentLayer % 3 == 0) {
393 | leftTopPadding = 2
394 | }
395 | if (currentLayer == totalLayer) {
396 | shadowalpha = "#"
397 | } else {
398 | layernumber = increment * currentLayer
399 | if (layernumber >= 17) {
400 | layernumber = 17
401 | }
402 | shadowalpha = alphaSet[layernumber]
403 | }
404 | var rectShape = RoundRectShape(floatArrayOf(
405 | localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2.toFloat(),
406 | localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2
407 | .toFloat()), null, null)
408 | if (totalLayer == currentLayer) {
409 | if (localRadius == 0) {
410 | localRadius = 2
411 | }
412 | rectShape = RoundRectShape(floatArrayOf(
413 | localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2.toFloat(),
414 | localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2.toFloat(), localRadius * 2
415 | .toFloat()), null, null)
416 | }
417 | val shapeDrawable = ShapeDrawable(rectShape)
418 | shapeDrawable.setPadding(leftTopPadding, leftTopPadding, rightPadding, bottomPadding)
419 | shapeDrawable.paint.color = Color.parseColor(shadowalpha + color)
420 | shapeDrawable.paint.style = Paint.Style.FILL
421 | shapeDrawable.paint.isAntiAlias = true
422 | shapeDrawable.paint.flags = Paint.ANTI_ALIAS_FLAG
423 | return shapeDrawable
424 | }
425 |
426 | /**
427 | * Parses the label text to truncate or hyphenize the string to fit in the given space
428 | *
429 | * @param labelText
430 | */
431 | private fun parseLabel(labelText: String?): String {
432 | val tokens = labelText!!.split(" ".toRegex()).toTypedArray()
433 | val finalizedString = StringBuilder()
434 | for (s in tokens) {
435 | if (s.length < 8) {
436 | finalizedString.append("""
437 | $s
438 |
439 | """.trimIndent())
440 | } else if (s.length >= 8 && s.length < 12) {
441 | finalizedString.append("""
442 | ${s.substring(0, 7)}
443 |
444 | """.trimIndent())
445 | finalizedString.append("""
446 | -${s.substring(7)}
447 |
448 | """.trimIndent())
449 | } else if (s.length >= 12 && s.length < 15) {
450 | finalizedString.append("""
451 | ${s.substring(0, 7)}
452 |
453 | """.trimIndent())
454 | finalizedString.append("""
455 | -${s.substring(7, 12)}
456 |
457 | """.trimIndent())
458 | if (s.length > 13) {
459 | finalizedString.append("""
460 | -${s.substring(13)}
461 |
462 | """.trimIndent())
463 | }
464 | } else {
465 | finalizedString.append("""
466 | ${s.substring(0, 5)}..
467 |
468 | """.trimIndent())
469 | }
470 | }
471 | finalizedString.deleteCharAt(finalizedString.length - 1)
472 | return finalizedString.toString()
473 | }
474 |
475 | /**
476 | * The animation function takes the actual view-group, animation duration and target width in dp as it's arguments
477 | * and takes initial width as 0 dp. After this, using ValueAnimator, the barview is made to expand to provided width
478 | * in the specified time duration and it's visibility is set to visible during animation.
479 | */
480 | class ResizeAnimation(var view: View, val targetHeight: Int, var startHeight: Int) : Animation() {
481 | override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
482 | val newHeight = (startHeight + targetHeight * interpolatedTime).toInt()
483 | //to support decent animation, change new heigt as Nico S. recommended in comments
484 | //int newHeight = (int) (startHeight+(targetHeight - startHeight) * interpolatedTime);
485 | view.layoutParams.height = newHeight
486 | view.requestLayout()
487 | }
488 |
489 | override fun initialize(width: Int, height: Int, parentWidth: Int, parentHeight: Int) {
490 | super.initialize(width, height, parentWidth, parentHeight)
491 | }
492 |
493 | override fun willChangeBounds(): Boolean {
494 | return true
495 | }
496 |
497 | }
498 |
499 | /**
500 | * This creates a gradient drawable background for the bars - sets a shape, a color and radius for the corners.
501 | *
502 | * @param color is the color in int which is used as the background color.
503 | */
504 | fun setUpRoundBars(color: Int): GradientDrawable {
505 | val gradientDrawable = GradientDrawable()
506 | gradientDrawable.shape = GradientDrawable.RECTANGLE
507 | gradientDrawable.setColor(color)
508 | gradientDrawable.cornerRadius = CORNER_RADIUS.toFloat()
509 | return gradientDrawable
510 | }
511 |
512 | fun setUpRoundBars(color: Int, highlightColor: Int): GradientDrawable {
513 | /**
514 | * This creates a gradient drawable background for the bars - sets a shape, a color and radius for the corners.
515 | * @param color is the color in int which is used as the background color.
516 | */
517 | val gradientDrawable = GradientDrawable()
518 | gradientDrawable.shape = GradientDrawable.RECTANGLE
519 | gradientDrawable.setColor(color)
520 | gradientDrawable.setStroke(5, highlightColor)
521 | gradientDrawable.cornerRadius = CORNER_RADIUS.toFloat()
522 | return gradientDrawable
523 | }
524 |
525 | /**
526 | * Generates a modified color for highlighting.
527 | *
528 | * @param backColor is the backcolor which will be used to highlight.
529 | * @param factor factor by which backcolor is to be changed.
530 | * @return modified color which is the color used as the backgroundcolor.
531 | */
532 | fun changeColor(backColor: Int, factor: Double): String {
533 | val modifiedColor: String
534 | val hsv = FloatArray(3)
535 | Color.colorToHSV(backColor, hsv)
536 | hsv[2] = hsv[2] * factor.toFloat()
537 | modifiedColor = String.format("#%06X", 0xFFFFFF and Color.HSVToColor(hsv))
538 | return modifiedColor
539 | }
540 |
541 | /**
542 | * to add shadow.
543 | *
544 | * @param numberOfLayers param to add shadow behind the bars.
545 | * @param layers param to add shadow behind the bars.
546 | */
547 | fun setLayerForBar(numberOfLayers: Int, layers: Array) {
548 | for (i in 0..numberOfLayers) {
549 | layers[i] = null
550 | }
551 | for (i in 0..numberOfLayers) {
552 | layers[i] = getRoundRect(color!!.substring(1), i, numberOfLayers, radius)
553 | }
554 | increaseHeight = 1f
555 | increaseWidth = 0
556 | if (this.numberOfLayers > 0) {
557 | increaseHeight = 1.2f + (numberOfLayers - 5) * 0.1f
558 | increaseWidth = 20 + (numberOfLayers - 5) * 4
559 | }
560 | }
561 |
562 | /**
563 | * to add shadow
564 | *
565 | * @param numberOfLayers param to add shadow behind the bars.
566 | * @param layers param to add shadow behind the bars.
567 | */
568 | fun setLayerForInitial(numberOfLayers: Int, layers: Array) {
569 | for (i in 0..numberOfLayers) {
570 | layers[i] = null
571 | }
572 | for (i in 0..numberOfLayers) {
573 | layers[i] = getRoundRect(color!!.substring(1), i, numberOfLayers, radius)
574 | }
575 | increaseHeight = 1f //To give some extra height of bar for shadow
576 | increaseWidth = 0 //To give some extra width of bar for shadow
577 | if (this.numberOfLayers > 0) {
578 | increaseHeight = 1.2f + (numberOfLayers - 5) * 0.1f
579 | increaseWidth = 15 + (numberOfLayers - 5) * 4
580 | }
581 | }
582 |
583 | /**
584 | * adds highlight, fade to the bars or deletes a bar completely after showing an alert dialogue.
585 | */
586 | fun addOptions() {
587 | val alertDialog = AlertDialog.Builder(mcontext)
588 | val layoutInflater = LayoutInflater.from(mcontext)
589 | val dialogueView = layoutInflater.inflate(R.layout.alert_dialogue, null)
590 | alertDialog.setView(dialogueView)
591 | val highlight = dialogueView.findViewById(R.id.highlight)
592 | val highlightColor = dialogueView.findViewById(R.id.highlightColor)
593 | val fade = dialogueView.findViewById(R.id.fade)
594 | val delete = dialogueView.findViewById(R.id.delete)
595 | highlight.setOnClickListener { highlightColor.visibility = View.VISIBLE }
596 | fade.setOnClickListener { highlightColor.visibility = View.GONE }
597 | delete.setOnClickListener { highlightColor.visibility = View.GONE }
598 | val green = dialogueView.findViewById(R.id.green)
599 | val blue = dialogueView.findViewById(R.id.blue)
600 | val pink = dialogueView.findViewById(R.id.pink)
601 | val yellow = dialogueView.findViewById(R.id.yellow)
602 | alertDialog.setPositiveButton("okay") { dialogInterface, i ->
603 | val colorOfHighlight: Int
604 | if (highlight.isChecked) {
605 | colorOfHighlight = assignColor(green, blue, pink, yellow)
606 | if (colorOfHighlight == 0) {
607 | Toast.makeText(mcontext, "Please Choose a Color", Toast.LENGTH_SHORT).show()
608 | } else {
609 | val myColor = changeColor(Color.parseColor(color), 0.7)
610 | bar.background = setUpRoundBars(Color.parseColor(myColor), colorOfHighlight)
611 | initial.background = setUpRoundBars(Color.parseColor(myColor), colorOfHighlight)
612 | bar.setOnLongClickListener {
613 | removeOptions(highlight, fade)
614 | true
615 | }
616 | }
617 | }
618 | if (fade.isChecked) {
619 | setAlphaValue(0.13.toFloat())
620 | bar.setOnLongClickListener {
621 | removeOptions(highlight, fade)
622 | true
623 | }
624 | }
625 | if (delete.isChecked) {
626 | removeViews()
627 | }
628 | }.setNegativeButton("cancel") { dialogInterface, i ->
629 | //Do nothing
630 | }.show()
631 | }
632 |
633 | /**
634 | * assigns a color which will be used as the highlight color.
635 | *
636 | * @param green Radio Button of the Alert Dialogue view which sets green color as highlight color if checked.
637 | * @param blue Radio Button of the Alert Dialogue view which sets blue color as highlight color if checked.
638 | * @param pink Radio Button of the Alert Dialogue view which sets pink color as highlight color if checked.
639 | * @param yellow Radio Button of the Alert Dialogue view which sets yellow color as highlight color if checked.
640 | * @return color which will be used to highlight.
641 | */
642 | fun assignColor(green: RadioButton, blue: RadioButton, pink: RadioButton, yellow: RadioButton): Int {
643 | var colorOfHighlight = 0
644 | if (green.isChecked) {
645 | colorOfHighlight = resources.getColor(R.color.greenHighlight)
646 | }
647 | if (blue.isChecked) {
648 | colorOfHighlight = resources.getColor(R.color.blueHighlight)
649 | }
650 | if (pink.isChecked) {
651 | colorOfHighlight = resources.getColor(R.color.pinkHighlight)
652 | }
653 | if (yellow.isChecked) {
654 | colorOfHighlight = resources.getColor(R.color.yellowHighlight)
655 | }
656 | return colorOfHighlight
657 | }
658 |
659 | /**
660 | * changes the alpha value so that the views are only slightly visible.
661 | *
662 | * @param alphaValue is used to assign an Alpha value.
663 | */
664 | fun setAlphaValue(alphaValue: Float) {
665 | bar.alpha = alphaValue
666 | initial.alpha = alphaValue
667 | label.alpha = alphaValue
668 | value.alpha = alphaValue
669 | }
670 |
671 | /**
672 | * sets the original background for bars - after highlight is removed.
673 | */
674 | fun setOriginalBackground() {
675 | val layers = arrayOfNulls(numberOfLayers + 1)
676 | setLayerForBar(numberOfLayers, layers)
677 | val splash_test_bar = LayerDrawable(layers)
678 | bar.background = splash_test_bar
679 | setLayerForInitial(numberOfLayers, layers)
680 | val splash_test_initial = LayerDrawable(layers)
681 | initial.background = splash_test_initial
682 | }
683 |
684 | /**
685 | * Removes all the views.
686 | */
687 | fun removeViews() {
688 | removeView(bar)
689 | removeView(initial)
690 | removeView(label)
691 | removeView(value)
692 | }
693 |
694 | /**
695 | * Generates an alert dialogue to remove the selected option.
696 | *
697 | * @param highlight Radio Button in dialogue view which highlights the bar if selected.
698 | * @param fade Radio Button in dialogue view which fades the bar if selected.
699 | */
700 | fun removeOptions(highlight: RadioButton, fade: RadioButton) {
701 | var message: String? = null
702 | if (highlight.isChecked) {
703 | message = resources.getString(R.string.removeHighlight)
704 | }
705 | if (fade.isChecked) {
706 | message = resources.getString(R.string.removeFade)
707 | }
708 | AlertDialog.Builder(mcontext).setMessage(message).setPositiveButton("yes") { dialogInterface, i ->
709 | if (highlight.isChecked) {
710 | setOriginalBackground()
711 | }
712 | if (fade.isChecked) {
713 | setAlphaValue(1f)
714 | }
715 | bar.setOnLongClickListener {
716 | addOptions()
717 | true
718 | }
719 | }.setNegativeButton("cancel") { dialogInterface, i ->
720 | //Do nothing
721 | }.show()
722 | }
723 |
724 | companion object {
725 | var fontCache = Hashtable()
726 |
727 | /**
728 | * Loads font from assets
729 | *
730 | * @param name
731 | * @param context
732 | */
733 | operator fun get(name: String, context: Context): Typeface? {
734 | var tf = fontCache[name]
735 | if (tf == null) {
736 | tf = try {
737 | Typeface.createFromAsset(context.assets, name)
738 | } catch (e: Exception) {
739 | return null
740 | }
741 | fontCache[name] = tf
742 | }
743 | return tf
744 | }
745 |
746 | /**
747 | * Animator function for the 'expand' intro animation
748 | *
749 | * @param v
750 | * @param duration
751 | * @param targetWidth
752 | */
753 | fun expand(v: View, duration: Int, targetWidth: Int) {
754 |
755 | //int prevWidth = v.getWidth();
756 | val prevWidth = 0
757 | v.visibility = View.VISIBLE
758 | val valueAnimator = ValueAnimator.ofInt(prevWidth, targetWidth)
759 | valueAnimator.addUpdateListener { animation ->
760 | v.layoutParams.width = animation.animatedValue as Int
761 | //v.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
762 | v.requestLayout()
763 | }
764 | valueAnimator.interpolator = DecelerateInterpolator()
765 | valueAnimator.duration = duration.toLong()
766 | valueAnimator.start()
767 | }
768 | }
769 | }
--------------------------------------------------------------------------------