diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index f333b5c2..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,103 +0,0 @@ -# Java Gradle CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-java/ for more details -# -version: 2 - -general: - branches: - only: - #- circleci -jobs: - build: - docker: - # specify the version you desire here - #- image: circleci/openjdk:8-jdk - - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - - image: circleci/android:api-28-alpha - - working_directory: ~/repo - - environment: - # Customize the JVM maximum heap limit - JVM_OPTS: -Xmx3200m - TERM: dumb -# KEYSTORE: ${CIRCLE_WORKING_DIRECTORY}/sigining.keystore -# PUBLISHER_ACCT_JSON_FILE: ${CIRCLE_WORKING_DIRECTORY}/publisher_profile.json - - steps: - - checkout - - - run: echo 'export KEYSTORE=${HOME}/repo/sigining.keystore' >> $BASH_ENV - - run: echo 'export PUBLISHER_ACCT_JSON_FILE=${HOME}/repo/publisher_profile.json' >> $BASH_ENV - - # Download and cache dependencies - - restore_cache: - keys: - - v1-dependencies-{{ checksum "build.gradle" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - # Get private keys etc - - run: ./misc/download_keystore.sh - - run: ./misc/inject_circle_build_number.sh - - - run: ./gradlew dependencies - - - save_cache: - paths: - - ~/.m2 - key: v1-dependencies-{{ checksum "build.gradle" }} - - # run tests & code coc! - - run: ./gradlew testDebugUnitTest jacocoTestDebugUnitTestReport - - # build release - - run: ./gradlew assembleRelease - - # javadoc - - run: ./gradlew javadoc - - # trigger codecod.io - - run: bash <(curl -s https://codecov.io/bash) - - - store_artifacts: - path: androidplot-core/build/outputs/aar/ - destination: aar - - - store_artifacts: - path: demoapp/build/outputs/apk/ - destination: apk - - - store_artifacts: - path: androidplot-core/build/reports/jacoco/debug/ - destination: coverage_report - - - store_artifacts: - path: androidplot-core/build/reports/tests/ - destination: test_results - - - store_artifacts: - path: androidplot-core/build/docs/javadoc - destination: javadoc - - - store_test_results: - path: androidplot-core/build/test-results/ - - - deploy: - name: "Deploy to Bintray" - command: | - if [ "${CIRCLE_BRANCH}" == "master" ]; - then ./gradlew bintrayUpload; - fi - - - deploy: - name: "Deploy to Google Play" - command: | - if [ "${CIRCLE_BRANCH}" == "master" ]; - then - ./misc/download_google_publisher_json.sh; - ./gradlew publishApkRelease - fi \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..d38f337e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,57 @@ +name: build androidplot +on: [push] +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Set Up JDK 17 + uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '17' + + - name: Build and Test + run: ./gradlew testDebugUnitTest jacocoTestDebugUnitTestReport + + - name: Build Release + env: + ENCODED: ${{ secrets.DEMOAPP_KEYSTORE }} + KEYSTORE: keystore.jks + KEY_ALIAS: Key0 + KEYSTORE_PASSWORD: ${{ secrets.DEMOAPP_KEYSTORE_PASSWORD }} + KEY_PASSWORD: ${{ secrets.DEMOAPP_KEY_PASSWORD }} + run: | + echo $ENCODED | base64 -di > "${GITHUB_WORKSPACE}/demoapp/keystore.jks" + ./gradlew assembleRelease + +# TODO: get javadoc working again at some point +# - name: Javadoc +# run: ./gradlew javadoc + + - name: Code Coverage + run: bash <(curl -s https://codecov.io/bash) + + - uses: actions/upload-artifact@v3 + with: + name: Core Library + path: androidplot-core/build/outputs/aar/*.aar + retention-days: 30 + + - uses: actions/upload-artifact@v3 + if: github.ref_name == 'master' + with: + name: Demoapp APK + path: demoapp/build/outputs/apk/release/*.apk + retention-days: 30 + + - name: Stage for Maven Central + if: github.ref_name == 'master' + env: + OSSRH_ACTOR: ${{ secrets.OSSRH_ACTOR }} + OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} + SIGNING_PASSWORD: ${{ secrets.GPG_SIGNING_PASSWORD }} + run: ./gradlew publish \ No newline at end of file diff --git a/README.md b/README.md index 7d7020d2..9617a26e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ -# ![image](docs/images/aplogo_small.png) Androidplot [![CircleCI](https://circleci.com/gh/halfhp/androidplot.svg?style=shield)](https://circleci.com/gh/halfhp/androidplot) [![codecov](https://codecov.io/gh/halfhp/androidplot/branch/master/graph/badge.svg)](https://codecov.io/gh/halfhp/androidplot) [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/androidplot.svg?style=social&label=Follow%20Us)](https://twitter.com/androidplot) +# ![image](docs/images/aplogo_small.png) Androidplot [![AndroidPlot](https://www.appbrain.com/stats/libraries/shield/androidplot.svg)](https://www.appbrain.com/stats/libraries/details/androidplot/androidplot) [![Codix](http://codix.io/gh/badge/halfhp/androidplot)](http://codix.io/gh/repo/halfhp/androidplot) [![codecov](https://codecov.io/gh/halfhp/androidplot/branch/master/graph/badge.svg)](https://codecov.io/gh/halfhp/androidplot) [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/androidplot.svg?style=social&label=Follow%20Us)](https://twitter.com/androidplot) -A library for creating dynamic and static charts in Android apps. It’s designed from the ground up for Android, -compatible with all versions of Android from 1.6 onward and is **used by over -[1,000 apps](http://www.appbrain.com/stats/libraries/details/androidplot/androidplot) on Google Play**. +A library for creating dynamic and static charts in Android apps. -[![Codix](http://codix.io/gh/badge/halfhp/androidplot)](http://codix.io/gh/repo/halfhp/androidplot) +Androidplot is compatible with all versions of Android from 1.6 onward, works equally with Kotlin and Java codebases +and is compatible with Jetpack compose. If you enjoy the lib, please [rate us on codix.io](http://codix.io/gh/repo/halfhp/androidplot)! @@ -43,7 +42,7 @@ Technical questions should be posted using the [androidplot tag](http://stackove # License Androidplot has been made available under the Apache 2.0 license: - Copyright 2018 Androidplot.com + Copyright 2021 Androidplot.com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/androidplot-core/build.gradle b/androidplot-core/build.gradle index e513a542..b37b2b4a 100644 --- a/androidplot-core/build.gradle +++ b/androidplot-core/build.gradle @@ -14,10 +14,12 @@ * limitations under the License. */ -apply plugin: 'com.android.library' -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: 'com.jfrog.bintray' -apply plugin: 'jacoco-android' +plugins { + id 'com.android.library' + id 'com.mxalbert.gradle.jacoco-android' + id 'maven-publish' + id 'signing' +} class AttrMarkdown extends DefaultTask { @@ -29,13 +31,14 @@ class AttrMarkdown extends DefaultTask { def input = project.file(inFile) def output = project.file(outFile) - if(output.exists()) { + if (output.exists()) { output.delete() } output.parentFile.mkdirs() - input.text.findAll(//) { match, g1 -> g1 - if(!g1.startsWith("NODOC")) { + input.text.findAll(//) { match, g1 -> + g1 + if (!g1.startsWith("NODOC")) { output.append(g1) output.append "\n\n" } @@ -51,16 +54,20 @@ class AttrMarkdown extends DefaultTask { * The generated doc will appear in / replace androidplot/docs/attrs.md */ task generateAttrsMarkdown(type: AttrMarkdown) { - inFile = { "src/main/res/values/attrs.xml"} + inFile = { "src/main/res/values/attrs.xml" } outFile = { "../docs/attrs.md" } } android { - compileSdkVersion theCompileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + defaultConfig { - versionCode theVersionCode - versionName theVersionName + compileSdk theCompileSdkVersion minSdkVersion theMinSdkVersion targetSdkVersion theTargetSdkVersion testApplicationId "com.androidplot.test" @@ -70,16 +77,21 @@ android { unitTests.all { jacoco { includeNoLocationClasses = true + jacoco.excludes = ['jdk.internal.*'] } } } - - /** - * TODO: enable and address lint issues. - */ - lintOptions { + lint { abortOnError false } + namespace 'com.androidplot' + + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } group = 'com.androidplot' @@ -90,99 +102,88 @@ def gitUrl = 'https://github.com/halfhp/androidplot.git' dependencies { - implementation 'com.halfhp.fig:figlib:1.0.7' - implementation 'com.android.support:support-annotations:28.0.0' - testImplementation "org.mockito:mockito-core:3.0.0" - testImplementation group: 'junit', name: 'junit', version: '4.12' - testImplementation "org.robolectric:robolectric:4.2.1" + implementation 'com.halfhp.fig:figlib:1.0.11' + implementation 'androidx.annotation:annotation:1.8.2' - // temp fix for: - // https://github.com/robolectric/robolectric/issues/1932 - testImplementation 'org.khronos:opengl-api:gl1.1-android-2.1_r1' + testImplementation "org.mockito:mockito-core:5.7.0" + testImplementation group: 'junit', name: 'junit', version: '4.13.2' + testImplementation "org.robolectric:robolectric:4.7.3" } -task javadoc(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - failOnError false - options { - links "http://docs.oracle.com/javase/7/docs/api/" - linksOffline "http://d.android.com/reference","${android.sdkDirectory}/docs/reference" - } - exclude '**/BuildConfig.java' - exclude '**/R.java' -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs -} +// TODO: get javadoc working again at some point +//task javadoc(type: Javadoc) { +// source = android.sourceSets.main.java.srcDirs +// classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) +// failOnError false +// options { +// links "http://docs.oracle.com/javase/7/docs/api/" +// linksOffline "http://d.android.com/reference","${android.sdkDirectory}/docs/reference" +// } +// exclude '**/BuildConfig.java' +// exclude '**/R.java' +//} +// + + +// TODO: get javadoc working again at some point +//javadoc { +// options.overview = "src/main/java/overview.html" +//} + +afterEvaluate { + publishing { + repositories { + maven { + name = "MavenCentral" + url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + credentials { + username = System.getenv("OSSRH_ACTOR") + password = System.getenv("OSSRH_TOKEN") + } + } + } -install { - repositories.mavenInstaller { - pom { - project { - packaging 'aar' - name 'Androidplot Core Library' - description = "Androidplot is a library for creating dynamic and static charts within your Android application." - url siteUrl - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + publications { + release(MavenPublication) { + from components.release + + // You can then customize attributes of the publication as shown below. + groupId = 'com.androidplot' + artifactId = 'androidplot-core' + version = theVersionName + + pom { + packaging 'aar' + name = 'Androidplot' + description = "Configure any object from XML." + url = gitUrl + licenses { + license { + name = 'The Apache Software License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } } - } - developers { - developer { - id 'halfhp' - name 'Nick Fellows' - email 'halfhp@gmail.com' + developers { + developer { + id = 'halfhp' + name = 'Nick Fellows' + email = 'halfhp@gmail.com' + } + } + scm { + connection = gitUrl + developerConnection = gitUrl + url = gitUrl } - } - scm { - connection gitUrl - developerConnection gitUrl - url siteUrl - } } } } } -bintray { - - // these environment vars must be set when deploying to bintray. - // note: BINTRAY_PASSWORD is actually the api key, but naming it 'password' - // tells the CI environment to obfuscate the value in public logs. - user = System.getenv('BINTRAY_USER') - key = System.getenv('BINTRAY_PASSWORD') - - - configurations = ['archives'] - pkg { - version { - name = theVersionName - } - repo = "androidplot" - name = "com.androidplot:androidplot-core" - issueTrackerUrl = "https://github.com/halfhp/androidplot/issues" - websiteUrl = siteUrl - vcsUrl = gitUrl - licenses = ["Apache-2.0"] - } -} - -javadoc { - options.overview = "src/main/java/overview.html" -} - -artifacts { - archives javadocJar - archives sourcesJar +signing { + def signingKey = System.getenv("SIGNING_KEY") + def signingPassword = System.getenv("SIGNING_PASSWORD") + useInMemoryPgpKeys(signingKey, signingPassword) + sign(publishing.publications) } diff --git a/androidplot-core/src/main/AndroidManifest.xml b/androidplot-core/src/main/AndroidManifest.xml index e83183d1..3043c930 100644 --- a/androidplot-core/src/main/AndroidManifest.xml +++ b/androidplot-core/src/main/AndroidManifest.xml @@ -16,5 +16,5 @@ - + \ No newline at end of file diff --git a/androidplot-core/src/main/java/com/androidplot/Plot.java b/androidplot-core/src/main/java/com/androidplot/Plot.java index 47ef0fd6..63d2e831 100644 --- a/androidplot-core/src/main/java/com/androidplot/Plot.java +++ b/androidplot-core/src/main/java/com/androidplot/Plot.java @@ -26,11 +26,12 @@ import android.graphics.RectF; import android.os.Build; import android.os.Looper; -import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; +import androidx.annotation.Nullable; + import com.androidplot.ui.Anchor; import com.androidplot.ui.BoxModel; import com.androidplot.ui.Formatter; @@ -144,25 +145,25 @@ public enum BorderStyle { */ public enum RenderMode { /** - * Use a second thread and an off-screen buffer to do drawing. This is the preferred method - * of drawing dynamic data and static data that consists of a large number of points. This mode - * provides more efficient CPU utilization at the cost of increased memory usage. As of - * version 0.5.1 this is the default RenderMode. + * Do everything in the primary thread. This is the preferred method of drawing static charts + * and dynamic data that consists of a small number of points. This mode uses less memory at + * the cost of poor CPU utilization. * - * XML value: use_background_thread + * XML value: use_main_thread * @since 0.5.1 */ - USE_BACKGROUND_THREAD, + USE_MAIN_THREAD, /** - * Do everything in the primary thread. This is the preferred method of drawing static charts - * and dynamic data that consists of a small number of points. This mode uses less memory at - * the cost of poor CPU utilization. + * Use a second thread and an off-screen buffer to do drawing. This is the preferred method + * of drawing dynamic data and static data that consists of a large number of points. This mode + * provides more efficient CPU utilization at the cost of increased memory usage. As of + * version 0.5.1 this is the default RenderMode. * - * XML value: use_main_thread + * XML value: use_background_thread * @since 0.5.1 */ - USE_MAIN_THREAD + USE_BACKGROUND_THREAD } private BoxModel boxModel = new BoxModel(); @@ -211,6 +212,8 @@ public enum RenderMode { * that is being used. */ private static class BufferedCanvas { + private int lastHeight = 0; + private int lastWidth = 0; private volatile Bitmap bgBuffer; // all drawing is done on this buffer. private volatile Bitmap fgBuffer; private Canvas canvas = new Canvas(); @@ -225,11 +228,21 @@ public synchronized void swap() { fgBuffer = tmp; } + /** + * Used when rendering in background mode and a view is attached + * but not resized, so that rendering buffers will be reinitialized. + */ + public void resizeToLast() { + resize(lastHeight, lastWidth); + } + public synchronized void resize(int h, int w) { if (w <= 0 || h <= 0) { bgBuffer = null; fgBuffer = null; } else { + lastHeight = h; + lastWidth = w; try { bgBuffer = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); fgBuffer = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); @@ -407,35 +420,43 @@ protected final void init(Context context, AttributeSet attrs, int defStyle) { layoutManager.onPostInit(); if (renderMode == RenderMode.USE_BACKGROUND_THREAD) { - renderThread = new Thread(new Runnable() { - @Override - public void run() { - - keepRunning = true; - while (keepRunning) { - isIdle = false; - synchronized (pingPong) { - Canvas c = pingPong.getCanvas(); - renderOnCanvas(c); - pingPong.swap(); - } - synchronized (renderSync) { - postInvalidate(); - // prevent this thread from becoming an orphan - // after the view is destroyed - if (keepRunning) { - try { - renderSync.wait(); - } catch (InterruptedException e) { - keepRunning = false; - } - } + startBackgroundRendering(); + } + } + + protected void startBackgroundRendering() { + if(renderThread != null) { + return; + } + + renderThread = new Thread(() -> { + System.out.println("Thread started with id " + this.hashCode()); + + keepRunning = true; + while (keepRunning) { + isIdle = false; + synchronized (pingPong) { + Canvas c = pingPong.getCanvas(); + renderOnCanvas(c); + pingPong.swap(); + } + synchronized (renderSync) { + postInvalidate(); + // prevent this thread from becoming an orphan + // after the view is destroyed + if (keepRunning) { + try { + renderSync.wait(); + } catch (InterruptedException e) { + keepRunning = false; } } - pingPong.recycle(); } - }, "Androidplot renderThread"); - } + } + System.out.println("Thread exited with id " + this.hashCode()); + renderThread = null; + pingPong.recycle(); + }, "Androidplot renderThread"); } /** @@ -744,11 +765,12 @@ public void redraw() { // only enter synchronized block if the call is expected to block OR // if the render thread is idle, so we know that we won't have to wait to // obtain a lock. - if (isIdle) { + if (renderThread != null && isIdle) { synchronized (renderSync) { renderSync.notify(); } } + } else if(renderMode == RenderMode.USE_MAIN_THREAD) { // are we on the UI thread? @@ -777,6 +799,17 @@ protected void onDetachedFromWindow() { } } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + // necessary to support rendering in recyclerview etc. + if(renderMode == RenderMode.USE_BACKGROUND_THREAD && renderThread == null) { + pingPong.resizeToLast(); + startBackgroundRendering(); + renderThread.start(); + } + } @Override protected synchronized void onSizeChanged (int w, int h, int oldw, int oldh) { diff --git a/androidplot-core/src/main/java/com/androidplot/pie/PieLegendItem.java b/androidplot-core/src/main/java/com/androidplot/pie/PieLegendItem.java index 8b4e9913..669b188b 100644 --- a/androidplot-core/src/main/java/com/androidplot/pie/PieLegendItem.java +++ b/androidplot-core/src/main/java/com/androidplot/pie/PieLegendItem.java @@ -1,7 +1,7 @@ package com.androidplot.pie; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.ui.widget.LegendItem; diff --git a/androidplot-core/src/main/java/com/androidplot/pie/PieLegendWidget.java b/androidplot-core/src/main/java/com/androidplot/pie/PieLegendWidget.java index c59b7f0b..4d1ccd03 100644 --- a/androidplot-core/src/main/java/com/androidplot/pie/PieLegendWidget.java +++ b/androidplot-core/src/main/java/com/androidplot/pie/PieLegendWidget.java @@ -2,7 +2,7 @@ import android.graphics.Canvas; import android.graphics.RectF; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.ui.LayoutManager; import com.androidplot.ui.SeriesBundle; diff --git a/androidplot-core/src/main/java/com/androidplot/ui/PositionMetrics.java b/androidplot-core/src/main/java/com/androidplot/ui/PositionMetrics.java index 88efddcb..377e9e04 100644 --- a/androidplot-core/src/main/java/com/androidplot/ui/PositionMetrics.java +++ b/androidplot-core/src/main/java/com/androidplot/ui/PositionMetrics.java @@ -16,7 +16,7 @@ package com.androidplot.ui; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; public class PositionMetrics implements Comparable { diff --git a/androidplot-core/src/main/java/com/androidplot/ui/widget/LegendWidget.java b/androidplot-core/src/main/java/com/androidplot/ui/widget/LegendWidget.java index e9222888..0da56a3a 100644 --- a/androidplot-core/src/main/java/com/androidplot/ui/widget/LegendWidget.java +++ b/androidplot-core/src/main/java/com/androidplot/ui/widget/LegendWidget.java @@ -4,7 +4,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.ui.LayoutManager; import com.androidplot.ui.Size; import com.androidplot.ui.TableModel; diff --git a/androidplot-core/src/main/java/com/androidplot/ui/widget/Widget.java b/androidplot-core/src/main/java/com/androidplot/ui/widget/Widget.java index 87a43a02..6d21767b 100644 --- a/androidplot-core/src/main/java/com/androidplot/ui/widget/Widget.java +++ b/androidplot-core/src/main/java/com/androidplot/ui/widget/Widget.java @@ -17,8 +17,8 @@ package com.androidplot.ui.widget; import android.graphics.*; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.Nullable; +import androidx.annotation.NonNull; import com.androidplot.ui.*; import com.androidplot.util.DisplayDimensions; diff --git a/androidplot-core/src/main/java/com/androidplot/util/FastNumber.java b/androidplot-core/src/main/java/com/androidplot/util/FastNumber.java index 72e8a25d..4fa11d8a 100644 --- a/androidplot-core/src/main/java/com/androidplot/util/FastNumber.java +++ b/androidplot-core/src/main/java/com/androidplot/util/FastNumber.java @@ -1,7 +1,7 @@ package com.androidplot.util; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; /** * An extension of {@link Number} optimized for speed at the cost of memory. diff --git a/androidplot-core/src/main/java/com/androidplot/xy/FastLineAndPointRenderer.java b/androidplot-core/src/main/java/com/androidplot/xy/FastLineAndPointRenderer.java index 5f469ce2..df070325 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/FastLineAndPointRenderer.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/FastLineAndPointRenderer.java @@ -20,7 +20,7 @@ import android.graphics.Paint; import android.graphics.PointF; import android.graphics.RectF; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.ui.RenderStack; import com.androidplot.ui.SeriesRenderer; diff --git a/androidplot-core/src/main/java/com/androidplot/xy/FixedSizeEditableXYSeries.java b/androidplot-core/src/main/java/com/androidplot/xy/FixedSizeEditableXYSeries.java index 0e6ea1a1..36ff371e 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/FixedSizeEditableXYSeries.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/FixedSizeEditableXYSeries.java @@ -1,7 +1,7 @@ package com.androidplot.xy; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.androidplot.util.FastNumber; diff --git a/androidplot-core/src/main/java/com/androidplot/xy/PanZoom.java b/androidplot-core/src/main/java/com/androidplot/xy/PanZoom.java index 33d61369..9cd80847 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/PanZoom.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/PanZoom.java @@ -2,7 +2,7 @@ import android.graphics.RectF; import android.graphics.PointF; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.view.*; import com.androidplot.*; diff --git a/androidplot-core/src/main/java/com/androidplot/xy/XYConstraints.java b/androidplot-core/src/main/java/com/androidplot/xy/XYConstraints.java index 58338264..c4452d33 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/XYConstraints.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/XYConstraints.java @@ -16,8 +16,8 @@ package com.androidplot.xy; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; /** * Calculates the min/max constraints for an xy plane. diff --git a/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java b/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java index af1f2729..8fa0571f 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java @@ -22,8 +22,8 @@ import android.graphics.Paint; import android.graphics.PointF; import android.graphics.RectF; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.androidplot.R; import com.androidplot.Region; @@ -564,7 +564,7 @@ protected void doOnDraw(Canvas canvas, RectF widgetRect) { } protected void drawDomainLine(Canvas canvas, float xPix, Number xVal, - Paint linePaint, boolean isOrigin) { + Paint linePaint, boolean isOrigin, boolean shouldDrawLabel) { // lines if (linePaint != null) { @@ -574,12 +574,19 @@ protected void drawDomainLine(Canvas canvas, float xPix, Number xVal, } // labels - drawLineLabel(canvas, Edge.TOP, xVal, xPix, labelRect.top, isOrigin); - drawLineLabel(canvas, Edge.BOTTOM, xVal, xPix, labelRect.bottom, isOrigin); + if(shouldDrawLabel) { + if (isLineLabelEnabled(Edge.TOP)) { + drawLineLabel(canvas, Edge.TOP, xVal, xPix, labelRect.top, isOrigin); + } + + if (isLineLabelEnabled(Edge.BOTTOM)) { + drawLineLabel(canvas, Edge.BOTTOM, xVal, xPix, labelRect.bottom, isOrigin); + } + } } protected void drawRangeLine(Canvas canvas, float yPix, Number yVal, - Paint linePaint, boolean isOrigin) { + Paint linePaint, boolean isOrigin, boolean shouldDrawLabel) { // lines if (linePaint != null) { canvas.drawLine(gridRect.left - lineExtensionLeft, yPix, @@ -587,9 +594,15 @@ protected void drawRangeLine(Canvas canvas, float yPix, Number yVal, ); } - // labels - drawLineLabel(canvas, Edge.LEFT, yVal, labelRect.left, yPix, isOrigin); - drawLineLabel(canvas, Edge.RIGHT, yVal, labelRect.right, yPix, isOrigin); + if(shouldDrawLabel) { + // labels + if (isLineLabelEnabled(Edge.LEFT)) { + drawLineLabel(canvas, Edge.LEFT, yVal, labelRect.left, yPix, isOrigin); + } + if (isLineLabelEnabled(Edge.RIGHT)) { + drawLineLabel(canvas, Edge.RIGHT, yVal, labelRect.right, yPix, isOrigin); + } + } } protected void drawLineLabel(Canvas canvas, @@ -598,9 +611,7 @@ protected void drawLineLabel(Canvas canvas, float x, float y, boolean isOrigin) { - if (isLineLabelEnabled(edge)) { - getLineLabelRenderer(edge).drawLabel(canvas, getLineLabelStyle(edge), val, x, y, isOrigin); - } + getLineLabelRenderer(edge).drawLabel(canvas, getLineLabelStyle(edge), val, x, y, isOrigin); } /** @@ -646,7 +657,7 @@ protected void drawGrid(Canvas canvas) { } else { linePaint = domainSubGridLinePaint; } - drawDomainLine(canvas, (float) xPix, xVal, linePaint, isOrigin); + drawDomainLine(canvas, (float) xPix, xVal, linePaint, isOrigin, isMajorTick); } Number rangeOrigin = plot.getRangeOrigin(); @@ -684,7 +695,7 @@ protected void drawGrid(Canvas canvas) { } else { linePaint = rangeSubGridLinePaint; } - drawRangeLine(canvas, (float) yPix, yVal, linePaint, isOrigin); + drawRangeLine(canvas, (float) yPix, yVal, linePaint, isOrigin, isMajorTick); } } diff --git a/androidplot-core/src/main/java/com/androidplot/xy/XYLegendItem.java b/androidplot-core/src/main/java/com/androidplot/xy/XYLegendItem.java index 1fd10ebd..51c67159 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/XYLegendItem.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/XYLegendItem.java @@ -1,6 +1,6 @@ package com.androidplot.xy; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.ui.widget.LegendItem; diff --git a/androidplot-core/src/main/java/com/androidplot/xy/XYLegendWidget.java b/androidplot-core/src/main/java/com/androidplot/xy/XYLegendWidget.java index f08783cb..680fd4b2 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/XYLegendWidget.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/XYLegendWidget.java @@ -17,7 +17,7 @@ package com.androidplot.xy; import android.graphics.*; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.ui.LayoutManager; import com.androidplot.ui.SeriesBundle; diff --git a/androidplot-core/src/main/java/com/androidplot/xy/XYPlot.java b/androidplot-core/src/main/java/com/androidplot/xy/XYPlot.java index 67eaafa8..e519b5a0 100644 --- a/androidplot-core/src/main/java/com/androidplot/xy/XYPlot.java +++ b/androidplot-core/src/main/java/com/androidplot/xy/XYPlot.java @@ -22,7 +22,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.util.AttributeSet; import com.androidplot.Plot; diff --git a/androidplot-core/src/main/res/values/attrs.xml b/androidplot-core/src/main/res/values/attrs.xml index 535ccf18..5c714912 100644 --- a/androidplot-core/src/main/res/values/attrs.xml +++ b/androidplot-core/src/main/res/values/attrs.xml @@ -30,8 +30,8 @@ Supported Elements: - + diff --git a/androidplot-core/src/test/java/com/androidplot/PlotTest.java b/androidplot-core/src/test/java/com/androidplot/PlotTest.java index 5a750afd..9e4753bf 100644 --- a/androidplot-core/src/test/java/com/androidplot/PlotTest.java +++ b/androidplot-core/src/test/java/com/androidplot/PlotTest.java @@ -34,6 +34,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -44,7 +45,8 @@ public class PlotTest extends AndroidplotTest { @Test public void testInit_withoutAttrs() { - Plot plot = mock(Plot.class); + //Plot plot = mock(Plot.class); + Plot plot = spy(new MockPlot("MockPlot")); plot.init(RuntimeEnvironment.application, null, 0); verify(plot, times(1)).onPreInit(); @@ -53,10 +55,12 @@ public void testInit_withoutAttrs() { @Test public void testInit_withAttrs() { - Plot plot = new MockPlot("MockPlot"); + Plot plot = spy(new MockPlot("MockPlot")); AttributeSet attrs = mock(AttributeSet.class); plot.init(RuntimeEnvironment.application, attrs, 0); - // TODO: verifications + + verify(plot, times(1)).onPreInit(); + verify(plot, times(1)).onAfterConfig(); } @Test diff --git a/androidplot-core/src/test/java/com/androidplot/ui/widget/TextLabelWidgetTest.java b/androidplot-core/src/test/java/com/androidplot/ui/widget/TextLabelWidgetTest.java index 6ed81b7b..bdb48f92 100644 --- a/androidplot-core/src/test/java/com/androidplot/ui/widget/TextLabelWidgetTest.java +++ b/androidplot-core/src/test/java/com/androidplot/ui/widget/TextLabelWidgetTest.java @@ -14,9 +14,9 @@ import org.mockito.InOrder; import org.mockito.Mock; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyFloat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; diff --git a/androidplot-core/src/test/java/com/androidplot/ui/widget/WidgetTest.java b/androidplot-core/src/test/java/com/androidplot/ui/widget/WidgetTest.java index 408edc33..cae6c056 100644 --- a/androidplot-core/src/test/java/com/androidplot/ui/widget/WidgetTest.java +++ b/androidplot-core/src/test/java/com/androidplot/ui/widget/WidgetTest.java @@ -2,7 +2,7 @@ import android.graphics.Canvas; import android.graphics.RectF; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.test.AndroidplotTest; import com.androidplot.ui.Anchor; @@ -21,10 +21,10 @@ import org.mockito.Mockito; import static junit.framework.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -94,9 +94,9 @@ public void draw_sizeChanged_invokesOnResizeBeforeDoOnDraw() { widget.draw(canvas); - inOrder.verify(widget).onResize(isNull(RectF.class), any(RectF.class)); + inOrder.verify(widget).onResize(isNull(), any(RectF.class)); inOrder.verify(widget).doOnDraw(eq(canvas), any(RectF.class)); - verify(widget).onResize(isNull(RectF.class), any(RectF.class)); + verify(widget).onResize(isNull(), any(RectF.class)); } static class TestWidget extends Widget { diff --git a/androidplot-core/src/test/java/com/androidplot/util/PlotStatisticsTest.java b/androidplot-core/src/test/java/com/androidplot/util/PlotStatisticsTest.java index b063235a..4454c69c 100644 --- a/androidplot-core/src/test/java/com/androidplot/util/PlotStatisticsTest.java +++ b/androidplot-core/src/test/java/com/androidplot/util/PlotStatisticsTest.java @@ -27,9 +27,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyFloat; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/androidplot-core/src/test/java/com/androidplot/xy/AdvanceLineAndPointRendererTest.java b/androidplot-core/src/test/java/com/androidplot/xy/AdvanceLineAndPointRendererTest.java index 647882c5..b1600828 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/AdvanceLineAndPointRendererTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/AdvanceLineAndPointRendererTest.java @@ -24,7 +24,6 @@ import org.junit.*; import org.mockito.*; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; /** diff --git a/androidplot-core/src/test/java/com/androidplot/xy/BarRendererTest.java b/androidplot-core/src/test/java/com/androidplot/xy/BarRendererTest.java index e4624d08..08cc1480 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/BarRendererTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/BarRendererTest.java @@ -33,9 +33,9 @@ import java.util.List; import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyFloat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; diff --git a/androidplot-core/src/test/java/com/androidplot/xy/BubbleRendererTest.java b/androidplot-core/src/test/java/com/androidplot/xy/BubbleRendererTest.java index cd0ff2b1..94a0be50 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/BubbleRendererTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/BubbleRendererTest.java @@ -24,7 +24,6 @@ import org.junit.*; import org.mockito.*; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; /** diff --git a/androidplot-core/src/test/java/com/androidplot/xy/CandlestickRendererTest.java b/androidplot-core/src/test/java/com/androidplot/xy/CandlestickRendererTest.java index a7fba775..8eda23b9 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/CandlestickRendererTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/CandlestickRendererTest.java @@ -24,7 +24,6 @@ import org.junit.*; import org.mockito.*; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; public class CandlestickRendererTest extends AndroidplotTest { diff --git a/androidplot-core/src/test/java/com/androidplot/xy/FastLineAndPointRendererTest.java b/androidplot-core/src/test/java/com/androidplot/xy/FastLineAndPointRendererTest.java index de81e70c..cf083d9e 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/FastLineAndPointRendererTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/FastLineAndPointRendererTest.java @@ -24,8 +24,8 @@ import org.junit.runner.*; import org.mockito.*; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/androidplot-core/src/test/java/com/androidplot/xy/LTTBSamplerTest.java b/androidplot-core/src/test/java/com/androidplot/xy/LTTBSamplerTest.java index 3269082d..800992f9 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/LTTBSamplerTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/LTTBSamplerTest.java @@ -27,7 +27,6 @@ import java.util.*; import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; public class LTTBSamplerTest extends AndroidplotTest { diff --git a/androidplot-core/src/test/java/com/androidplot/xy/LineAndPointRendererTest.java b/androidplot-core/src/test/java/com/androidplot/xy/LineAndPointRendererTest.java index 9cb03cd1..44a7b22d 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/LineAndPointRendererTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/LineAndPointRendererTest.java @@ -26,7 +26,6 @@ import java.util.*; import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; public class LineAndPointRendererTest extends AndroidplotTest { diff --git a/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java b/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java index 03897972..a9182501 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java @@ -21,7 +21,6 @@ import com.androidplot.test.*; import com.androidplot.ui.*; -import com.androidplot.util.DisplayDimensions; import org.junit.*; import org.mockito.*; @@ -29,12 +28,11 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyDouble; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyFloat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -202,7 +200,6 @@ public void drawCursorLabel_drawsText() { @Test public void setLineLabelEdges_setsEdges() { - graphWidget.setLineLabelEdges(XYGraphWidget.Edge.LEFT, XYGraphWidget.Edge.BOTTOM); assertTrue(graphWidget.isLineLabelEnabled(XYGraphWidget.Edge.LEFT)); assertTrue(graphWidget.isLineLabelEnabled(XYGraphWidget.Edge.BOTTOM)); @@ -298,10 +295,10 @@ public void seriesToScreenY_returnsScreenValue() { @Test public void setGridInsets_updatesGridRect() { - graphWidget.setGridInsets(new Insets(0, 0, 0, 0)); + graphWidget.setGridInsets(new com.androidplot.ui.Insets(0, 0, 0, 0)); final RectF oldRect = graphWidget.getGridRect(); - graphWidget.setGridInsets(new Insets(2, 2, 2, 2)); + graphWidget.setGridInsets(new com.androidplot.ui.Insets(2, 2, 2, 2)); final RectF newRect = graphWidget.getGridRect(); assertEquals(oldRect.left + 2, newRect.left); @@ -312,10 +309,10 @@ public void setGridInsets_updatesGridRect() { private void runDrawGridTest() { doNothing().when(graphWidget). - drawDomainLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean()); + drawDomainLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean(), anyBoolean()); doNothing().when(graphWidget). - drawRangeLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean()); + drawRangeLine(any(Canvas.class), anyFloat(), any(Number.class), any(Paint.class), anyBoolean(), anyBoolean()); xyPlot.setRangeBoundaries(0, 100, BoundaryMode.FIXED); xyPlot.setDomainBoundaries(0, 100, BoundaryMode.FIXED); @@ -324,9 +321,9 @@ private void runDrawGridTest() { // expecting a 100x100 grid to be drawn: verify(graphWidget, times(100)) - .drawDomainLine(eq(canvas), anyFloat(), anyDouble(), any(Paint.class), eq(false)); + .drawDomainLine(eq(canvas), anyFloat(), anyDouble(), any(Paint.class), eq(false), anyBoolean()); verify(graphWidget, times(100)) - .drawRangeLine(eq(canvas), anyFloat(), anyDouble(), any(Paint.class), eq(false)); + .drawRangeLine(eq(canvas), anyFloat(), anyDouble(), any(Paint.class), eq(false), anyBoolean()); } } diff --git a/androidplot-core/src/test/java/com/androidplot/xy/XYLegendWidgetTest.java b/androidplot-core/src/test/java/com/androidplot/xy/XYLegendWidgetTest.java index b50f7237..778fb40a 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/XYLegendWidgetTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/XYLegendWidgetTest.java @@ -32,11 +32,10 @@ import java.util.List; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/build.gradle b/build.gradle index a00c8e72..4b5e18de 100644 --- a/build.gradle +++ b/build.gradle @@ -14,34 +14,26 @@ * limitations under the License. */ -apply plugin: 'java' - -allprojects { - repositories { - jcenter() - } -} - ext { - theCompileSdkVersion = 28 - theTargetSdkVersion = 28 + theCompileSdkVersion = 34 + theTargetSdkVersion = 34 theMinSdkVersion = 5 - theVersionName = '1.5.7' - theVersionCode = 1 + theVersionName = '1.5.11' + theVersionCode = 227 + gitUrl = 'https://github.com/halfhp/androidplot.git' } buildscript { repositories { mavenCentral() - jcenter() + maven { url "https://plugins.gradle.org/m2/" } + maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots' } google() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' - classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4' + classpath 'com.android.tools.build:gradle:8.5.2' + classpath 'com.mxalbert.gradle:jacoco-android:0.2.0' } } diff --git a/demoapp-wearable/build.gradle b/demoapp-wearable/build.gradle index 22e5186d..666b353e 100644 --- a/demoapp-wearable/build.gradle +++ b/demoapp-wearable/build.gradle @@ -16,18 +16,14 @@ buildscript { repositories { - jcenter() google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.1' + classpath 'com.android.tools.build:gradle:3.1.4' } } -apply plugin: 'com.android.application' -repositories { - jcenter() -} +apply plugin: 'com.android.application' android { compileSdkVersion theCompileSdkVersion @@ -42,9 +38,10 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_6 - targetCompatibility JavaVersion.VERSION_1_6 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } + buildTypes { release { minifyEnabled false diff --git a/demoapp/build.gradle b/demoapp/build.gradle index 191280a5..2c2fbd52 100644 --- a/demoapp/build.gradle +++ b/demoapp/build.gradle @@ -14,40 +14,54 @@ * limitations under the License. */ -//apply plugin: 'com.android.application' -//apply plugin: 'com.github.triplet.play' - buildscript { - + ext.kotlin_version = '2.0.0' repositories { mavenCentral() } dependencies { - classpath 'com.github.triplet.gradle:play-publisher:2.2.1' + classpath 'com.github.triplet.gradle:play-publisher:3.6.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } plugins { id 'com.android.application' - id 'com.github.triplet.play' version '2.2.1' + id 'com.github.triplet.play' version '3.6.0' } +apply plugin: 'kotlin-android' + dependencies { + implementation "androidx.core:core-ktx:1.13.1" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation project(':androidplot-core') - implementation 'com.crittercism:crittercism-android-agent:5.4.0' + implementation 'androidx.recyclerview:recyclerview:1.3.2' - debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3' - releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3' - testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3' + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1' +} + +kotlin { + jvmToolchain(17) } android { + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + compileSdkVersion theCompileSdkVersion + buildFeatures { + viewBinding true + } + defaultConfig { versionCode theVersionCode versionName theVersionName - minSdkVersion 14 + minSdkVersion 19 targetSdkVersion theTargetSdkVersion applicationId "com.androidplot.demos" } @@ -71,18 +85,18 @@ android { debuggable true } } - - - /** - * TODO: uncomment this and address all the lint issues. - */ - lintOptions { + lint { abortOnError false } + namespace 'com.androidplot.demos' + } play { // see: https://github.com/Triple-T/gradle-play-publisher - serviceAccountCredentials = file(System.getenv("PUBLISHER_ACCT_JSON_FILE") ?: "publisher.json") + serviceAccountCredentials.set(file(System.getenv("PUBLISHER_ACCT_JSON_FILE") ?: "publisher.json")) track = 'beta' } +repositories { + mavenCentral() +} diff --git a/demoapp/project.properties b/demoapp/project.properties index 29656f2d..90a2cb18 100644 --- a/demoapp/project.properties +++ b/demoapp/project.properties @@ -39,5 +39,3 @@ #proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt # using config with optimization enabled so that things like log statement removal will work: proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt -# Project target. -target=android-16 diff --git a/demoapp/src/main/AndroidManifest.xml b/demoapp/src/main/AndroidManifest.xml index 89f1428f..5b73a2b7 100644 --- a/demoapp/src/main/AndroidManifest.xml +++ b/demoapp/src/main/AndroidManifest.xml @@ -15,7 +15,7 @@ ~ limitations under the License. --> - + @@ -27,75 +27,88 @@ android:icon="@drawable/ic_launcher"> + android:label="@string/app_name" + android:exported="true"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:screenOrientation="landscape" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> + android:label="@string/app_name" + android:exported="false"> - + + @@ -111,7 +124,8 @@ + android:name="com.androidplot.demos.widget.DemoAppWidgetProvider" + android:exported="false"> diff --git a/demoapp/src/main/java/com/androidplot/demos/AnimatedXYPlotActivity.java b/demoapp/src/main/java/com/androidplot/demos/AnimatedXYPlotActivity.java index 75d9553b..43d3adc0 100644 --- a/demoapp/src/main/java/com/androidplot/demos/AnimatedXYPlotActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/AnimatedXYPlotActivity.java @@ -21,7 +21,7 @@ import android.app.Activity; import android.graphics.Color; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.view.animation.AccelerateDecelerateInterpolator; import com.androidplot.xy.BoundaryMode; diff --git a/demoapp/src/main/java/com/androidplot/demos/CandlestickChartActivity.java b/demoapp/src/main/java/com/androidplot/demos/CandlestickChartActivity.java index 2c37580a..86ae1fbb 100644 --- a/demoapp/src/main/java/com/androidplot/demos/CandlestickChartActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/CandlestickChartActivity.java @@ -21,7 +21,7 @@ import android.graphics.DashPathEffect; import android.graphics.Paint; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.Region; import com.androidplot.util.PixelUtils; diff --git a/demoapp/src/main/java/com/androidplot/demos/DemoApplication.java b/demoapp/src/main/java/com/androidplot/demos/DemoApplication.java index 9c931a73..df3d6117 100644 --- a/demoapp/src/main/java/com/androidplot/demos/DemoApplication.java +++ b/demoapp/src/main/java/com/androidplot/demos/DemoApplication.java @@ -2,20 +2,10 @@ import android.app.*; -import com.squareup.leakcanary.*; - public class DemoApplication extends Application { @Override public void onCreate() { super.onCreate(); - initLeakCanary(); - } - - protected void initLeakCanary() { - if (LeakCanary.isInAnalyzerProcess(this)) { - return; - } - LeakCanary.install(this); } } diff --git a/demoapp/src/main/java/com/androidplot/demos/DualScaleActivity.java b/demoapp/src/main/java/com/androidplot/demos/DualScaleActivity.java index d164710a..f0116121 100644 --- a/demoapp/src/main/java/com/androidplot/demos/DualScaleActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/DualScaleActivity.java @@ -20,7 +20,7 @@ import android.graphics.Color; import android.graphics.DashPathEffect; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.util.PixelUtils; import com.androidplot.xy.BoundaryMode; diff --git a/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java b/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java index 590af815..290b7802 100644 --- a/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java @@ -20,7 +20,7 @@ import android.content.Context; import android.graphics.Color; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/demoapp/src/main/java/com/androidplot/demos/MainActivity.java b/demoapp/src/main/java/com/androidplot/demos/MainActivity.java deleted file mode 100644 index 86dadb68..00000000 --- a/demoapp/src/main/java/com/androidplot/demos/MainActivity.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2015 AndroidPlot.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.androidplot.demos; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import com.crittercism.app.Crittercism; - -public class MainActivity extends Activity { - - private static final String TAG = MainActivity.class.getName(); - - // DO *NOT* CHANGE THIS LINE! (CI-MATCH-POPULATE) - private static final String CRITTERCISM_APP_ID = null; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (CRITTERCISM_APP_ID != null) { - Log.d(TAG, "Crittercism initialized."); - Crittercism.initialize(getApplicationContext(), CRITTERCISM_APP_ID); - } - - setContentView(R.layout.main); - - Button startAnimatedXYPlotExButton = (Button) findViewById(R.id.animatedXYPlotExButton); - startAnimatedXYPlotExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, AnimatedXYPlotActivity.class)); - } - }); - - Button startScatterPlotExButton = (Button) findViewById(R.id.startScatterExButton); - startScatterPlotExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, ScatterPlotActivity.class)); - } - }); - - Button startSimplePieExButton = (Button) findViewById(R.id.startSimplePieExButton); - startSimplePieExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, SimplePieChartActivity.class)); - } - }); - - Button startDynamicXYExButton = (Button) findViewById(R.id.startDynamicXYExButton); - startDynamicXYExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, DynamicXYPlotActivity.class)); - } - }); - - Button startCandlestickExButton = (Button) findViewById(R.id.startCandlestickExButton); - startCandlestickExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, CandlestickChartActivity.class)); - } - }); - - Button startSimpleXYExButton = (Button) findViewById(R.id.startSimpleXYExButton); - startSimpleXYExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, SimpleXYPlotActivity.class)); - } - }); - - Button startBarPlotExButton = (Button) findViewById(R.id.startBarPlotExButton); - startBarPlotExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, BarPlotExampleActivity.class)); - } - }); - - Button startOrSensorExButton = (Button) findViewById(R.id.startOrSensorExButton); - startOrSensorExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, OrientationSensorExampleActivity.class)); - } - }); - - Button startDualScaleExButton = (Button) findViewById(R.id.startDualScaleExButton); - startDualScaleExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, DualScaleActivity.class)); - } - }); - - Button startTimeSeriesExButon = (Button) findViewById(R.id.startTimeSeriesExButton); - startTimeSeriesExButon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, TimeSeriesActivity.class)); - } - }); - - Button startStepChartExButton = (Button) findViewById(R.id.startStepChartExButton); - startStepChartExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, StepChartExampleActivity.class)); - } - }); - - Button startScrollZoomExButton = (Button) findViewById(R.id.startScrollZoomButton); - startScrollZoomExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, TouchZoomExampleActivity.class)); - } - }); - - Button startXyRegionExampleButton = (Button) findViewById(R.id.startXyRegionExampleButton); - startXyRegionExampleButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, XYRegionExampleActivity.class)); - } - }); - - - Button listViewExButton = (Button) findViewById(R.id.startXyListViewExButton); - listViewExButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, ListViewActivity.class)); - } - }); - - Button startXYPlotWithBgImgExampleButton = (Button) findViewById(R.id.startXYPlotWithBgImgExample); - startXYPlotWithBgImgExampleButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, XYPlotWithBgImgActivity.class)); - } - }); - - // ECG - Button startECGExampleButton = (Button) findViewById(R.id.startECGExample); - startECGExampleButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, ECGExample.class)); - } - }); - - // f(x) plot - Button fxPlotExampleButton = (Button) findViewById(R.id.fxPlotExample); - fxPlotExampleButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, FXPlotExampleActivity.class)); - } - }); - - // bubble chart - Button bubbleChartButton = (Button) findViewById(R.id.bubbleChartExample); - bubbleChartButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - startActivity(new Intent(MainActivity.this, BubbleChartActivity.class)); - } - }); - } -} diff --git a/demoapp/src/main/java/com/androidplot/demos/MainActivity.kt b/demoapp/src/main/java/com/androidplot/demos/MainActivity.kt new file mode 100644 index 00000000..6632af40 --- /dev/null +++ b/demoapp/src/main/java/com/androidplot/demos/MainActivity.kt @@ -0,0 +1,109 @@ +/* + * Copyright 2021 AndroidPlot.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.androidplot.demos + +import android.app.Activity +import android.os.Bundle +import android.content.Intent +import com.androidplot.demos.databinding.MainBinding + +class MainActivity : Activity() { + + private lateinit var binding: MainBinding + + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = MainBinding.inflate(layoutInflater) + + binding.animatedXYPlotExButton.setOnClickListener { + startActivity(Intent(this, AnimatedXYPlotActivity::class.java)) + } + + binding.startScatterExButton.setOnClickListener { + startActivity(Intent(this, ScatterPlotActivity::class.java)) + } + + binding.startSimplePieExButton.setOnClickListener { + startActivity(Intent(this, SimplePieChartActivity::class.java)) + } + + binding.startDynamicXYExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, DynamicXYPlotActivity::class.java)) + } + + binding.startCandlestickExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, CandlestickChartActivity::class.java)) + } + + binding.startSimpleXYExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, SimpleXYPlotActivity::class.java)) + } + + binding.startBarPlotExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, BarPlotExampleActivity::class.java)) + } + + binding.startOrSensorExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, OrientationSensorExampleActivity::class.java)) + } + + binding.startDualScaleExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, DualScaleActivity::class.java)) + } + + binding.startTimeSeriesExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, TimeSeriesActivity::class.java)) + } + + binding.startStepChartExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, StepChartExampleActivity::class.java)) + } + + binding.startScrollZoomButton.setOnClickListener { + startActivity(Intent(this@MainActivity, TouchZoomExampleActivity::class.java)) + } + + binding.startXyRegionExampleButton.setOnClickListener { + startActivity(Intent(this@MainActivity, XYRegionExampleActivity::class.java)) + } + + binding.startXyListViewExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, ListViewActivity::class.java)) + } + + binding.startXyRecyclerViewExButton.setOnClickListener { + startActivity(Intent(this@MainActivity, RecyclerViewActivity::class.java)) + } + + binding.startXYPlotWithBgImgExample.setOnClickListener { + startActivity(Intent(this@MainActivity, XYPlotWithBgImgActivity::class.java)) + } + + binding.startECGExample.setOnClickListener { + startActivity(Intent(this@MainActivity, ECGExample::class.java)) + } + + binding.fxPlotExample.setOnClickListener { + startActivity(Intent(this@MainActivity, FXPlotExampleActivity::class.java)) + } + + binding.bubbleChartExample.setOnClickListener { + startActivity(Intent(this@MainActivity, BubbleChartActivity::class.java)) + } + + setContentView(binding.root) + } +} \ No newline at end of file diff --git a/demoapp/src/main/java/com/androidplot/demos/RecyclerViewActivity.kt b/demoapp/src/main/java/com/androidplot/demos/RecyclerViewActivity.kt new file mode 100644 index 00000000..194ee6e0 --- /dev/null +++ b/demoapp/src/main/java/com/androidplot/demos/RecyclerViewActivity.kt @@ -0,0 +1,130 @@ +/* + * Copyright 2021 AndroidPlot.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.androidplot.demos + +import android.app.Activity +import android.graphics.Color +import com.androidplot.ui.SeriesBundle +import android.os.Bundle +import android.view.ViewGroup +import android.view.LayoutInflater +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.androidplot.demos.databinding.RecyclerviewExampleBinding +import com.androidplot.demos.databinding.RecyclerviewExampleItemBinding +import com.androidplot.util.PixelUtils +import com.androidplot.xy.* +import java.util.* + +class RecyclerViewActivity : Activity() { + private lateinit var binding: RecyclerviewExampleBinding + + companion object { + private const val NUM_PLOTS = 10 + private const val NUM_POINTS_PER_SERIES = 10 + private const val NUM_SERIES_PER_PLOT = 5 + } + + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + PixelUtils.init(this) + + binding = RecyclerviewExampleBinding.inflate(layoutInflater) + setContentView(binding.root) + + binding.recyclerView.setHasFixedSize(true) + binding.recyclerView.layoutManager = LinearLayoutManager(this) + binding.recyclerView.adapter = MyRecyclerViewAdapter() + } + + class MyRecyclerViewHolder( + private val binding: RecyclerviewExampleItemBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(data: List>, title: String) { + val plot = binding.plot + plot.clear() + plot.title.text = title + data.map { plot.addSeries(it.series, it.formatter) } + plot.redraw() + } + } + + class MyRecyclerViewAdapter : RecyclerView.Adapter() { + private val seriesData = generateData() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewHolder { + val itemBinding = RecyclerviewExampleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return MyRecyclerViewHolder(itemBinding) + } + + override fun onBindViewHolder(holder: MyRecyclerViewHolder, position: Int) { + holder.bind(seriesData[position], "Series $position") + } + + override fun getItemCount() = seriesData.size + + private fun generateData(): List>> { + val theData = mutableListOf>>() + fun generateBundle(seriesLabel: String): SeriesBundle { + val generator = Random() + val nums = ArrayList() + for (j in 0 until NUM_POINTS_PER_SERIES) { + nums.add(generator.nextFloat()) + } + + val formatter = LineAndPointFormatter( + Color.rgb( + java.lang.Double.valueOf(Math.random() * 255).toInt(), + java.lang.Double.valueOf(Math.random() * 255).toInt(), + java.lang.Double.valueOf(Math.random() * 255).toInt() + ), + Color.rgb( + java.lang.Double.valueOf(Math.random() * 255).toInt(), + java.lang.Double.valueOf(Math.random() * 255).toInt(), + java.lang.Double.valueOf(Math.random() * 255).toInt() + ), + null, null + ) + + // for fun, configure interpolation on the formatter: + formatter.interpolationParams = CatmullRomInterpolator.Params( + 20, + CatmullRomInterpolator.Type.Centripetal + ) + + return SeriesBundle( + SimpleXYSeries( + nums, + SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, + seriesLabel + ), + formatter + ) + } + + for (i in 0 until NUM_PLOTS) { + val seriesList: MutableList> = + ArrayList(NUM_SERIES_PER_PLOT) + + for (k in 0 until NUM_SERIES_PER_PLOT) { + seriesList.add(generateBundle("S$k")) + } + theData.add(seriesList) + } + return theData + } + } +} \ No newline at end of file diff --git a/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java b/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java index 46118949..db3a5a28 100644 --- a/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/SimpleXYPlotActivity.java @@ -19,7 +19,7 @@ import android.app.Activity; import android.graphics.DashPathEffect; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.util.PixelUtils; import com.androidplot.xy.CatmullRomInterpolator; diff --git a/demoapp/src/main/java/com/androidplot/demos/StepChartExampleActivity.java b/demoapp/src/main/java/com/androidplot/demos/StepChartExampleActivity.java index 79b8272f..4b1fdc35 100644 --- a/demoapp/src/main/java/com/androidplot/demos/StepChartExampleActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/StepChartExampleActivity.java @@ -23,7 +23,7 @@ import android.graphics.Paint; import android.graphics.Shader; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.util.PixelUtils; import com.androidplot.xy.SimpleXYSeries; diff --git a/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java b/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java index 9a8da790..12930bd7 100644 --- a/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java @@ -22,7 +22,7 @@ import android.graphics.DashPathEffect; import android.graphics.Paint; import android.os.Bundle; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.androidplot.util.PixelUtils; import com.androidplot.xy.BoundaryMode; diff --git a/demoapp/src/main/res/layout/main.xml b/demoapp/src/main/res/layout/main.xml index 590087de..3a2d873f 100644 --- a/demoapp/src/main/res/layout/main.xml +++ b/demoapp/src/main/res/layout/main.xml @@ -118,6 +118,13 @@ android:text="ListView of XYPlots" android:enabled="true"/> +