From 3c1da1a5dab6c9f198624b7e894c5a8eec66311a Mon Sep 17 00:00:00 2001 From: JackJackE <37071007+mtjin@users.noreply.github.com> Date: Thu, 26 Dec 2019 00:33:31 +0900 Subject: [PATCH 01/28] upgrade gradle version and refactoring code in a line that doesn't affect the program (#99) --- androidplot-core/build.gradle | 4 ++-- build.gradle | 4 ++-- .../demos/BarPlotExampleActivity.java | 2 ++ .../androidplot/demos/DynamicXYPlotActivity.java | 16 ++++++++-------- .../java/com/androidplot/demos/ECGExample.java | 6 +++--- .../com/androidplot/demos/ListViewActivity.java | 8 ++++---- .../demos/SimplePieChartActivity.java | 2 ++ .../androidplot/demos/TimeSeriesActivity.java | 2 ++ 8 files changed, 25 insertions(+), 19 deletions(-) diff --git a/androidplot-core/build.gradle b/androidplot-core/build.gradle index 0592389b..e513a542 100644 --- a/androidplot-core/build.gradle +++ b/androidplot-core/build.gradle @@ -92,9 +92,9 @@ dependencies { implementation 'com.halfhp.fig:figlib:1.0.7' implementation 'com.android.support:support-annotations:28.0.0' - testImplementation "org.mockito:mockito-core:2.13.0" + testImplementation "org.mockito:mockito-core:3.0.0" testImplementation group: 'junit', name: 'junit', version: '4.12' - testImplementation "org.robolectric:robolectric:4.0.1" + testImplementation "org.robolectric:robolectric:4.2.1" // temp fix for: // https://github.com/robolectric/robolectric/issues/1932 diff --git a/build.gradle b/build.gradle index 41312fc7..a00c8e72 100644 --- a/build.gradle +++ b/build.gradle @@ -38,9 +38,9 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' + 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.0' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4' } } diff --git a/demoapp/src/main/java/com/androidplot/demos/BarPlotExampleActivity.java b/demoapp/src/main/java/com/androidplot/demos/BarPlotExampleActivity.java index 8d8720d1..3cc2faa4 100644 --- a/demoapp/src/main/java/com/androidplot/demos/BarPlotExampleActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/BarPlotExampleActivity.java @@ -22,6 +22,7 @@ import java.text.ParsePosition; import java.util.Arrays; +import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Color; import android.graphics.Paint; @@ -86,6 +87,7 @@ private enum SeriesSize { private Pair selection; + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { diff --git a/demoapp/src/main/java/com/androidplot/demos/DynamicXYPlotActivity.java b/demoapp/src/main/java/com/androidplot/demos/DynamicXYPlotActivity.java index f76dca01..f18b518b 100644 --- a/demoapp/src/main/java/com/androidplot/demos/DynamicXYPlotActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/DynamicXYPlotActivity.java @@ -138,8 +138,8 @@ public void notifyObservers() { private static final int MAX_AMP_SEED = 100; private static final int MIN_AMP_SEED = 10; private static final int AMP_STEP = 1; - public static final int SINE1 = 0; - public static final int SINE2 = 1; + static final int SINE1 = 0; + static final int SINE2 = 1; private static final int SAMPLE_SIZE = 31; private int phase = 0; private int sinAmp = 1; @@ -150,7 +150,7 @@ public void notifyObservers() { notifier = new MyObservable(); } - public void stopThread() { + void stopThread() { keepRunning = false; } @@ -181,18 +181,18 @@ public void run() { } } - public int getItemCount(int series) { + int getItemCount(int series) { return SAMPLE_SIZE; } - public Number getX(int series, int index) { + Number getX(int series, int index) { if (index >= SAMPLE_SIZE) { throw new IllegalArgumentException(); } return index; } - public Number getY(int series, int index) { + Number getY(int series, int index) { if (index >= SAMPLE_SIZE) { throw new IllegalArgumentException(); } @@ -208,7 +208,7 @@ public Number getY(int series, int index) { } } - public void addObserver(Observer observer) { + void addObserver(Observer observer) { notifier.addObserver(observer); } @@ -223,7 +223,7 @@ class SampleDynamicSeries implements XYSeries { private int seriesIndex; private String title; - public SampleDynamicSeries(SampleDynamicXYDatasource datasource, int seriesIndex, String title) { + SampleDynamicSeries(SampleDynamicXYDatasource datasource, int seriesIndex, String title) { this.datasource = datasource; this.seriesIndex = seriesIndex; this.title = title; diff --git a/demoapp/src/main/java/com/androidplot/demos/ECGExample.java b/demoapp/src/main/java/com/androidplot/demos/ECGExample.java index 31d71e87..2bd7dec5 100644 --- a/demoapp/src/main/java/com/androidplot/demos/ECGExample.java +++ b/demoapp/src/main/java/com/androidplot/demos/ECGExample.java @@ -82,7 +82,7 @@ public static class MyFadeFormatter extends AdvancedLineAndPointRenderer.Formatt private int trailSize; - public MyFadeFormatter(int trailSize) { + MyFadeFormatter(int trailSize) { this.trailSize = trailSize; } @@ -125,7 +125,7 @@ public static class ECGModel implements XYSeries { * @param size Sample size contained within this model * @param updateFreqHz Frequency at which new samples are added to the model */ - public ECGModel(int size, int updateFreqHz) { + ECGModel(int size, int updateFreqHz) { data = new Number[size]; for(int i = 0; i < data.length; i++) { data[i] = 0; @@ -176,7 +176,7 @@ public void run() { }); } - public void start(final WeakReference rendererRef) { + void start(final WeakReference rendererRef) { this.rendererRef = rendererRef; keepRunning = true; thread.start(); diff --git a/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java b/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java index 9d640053..590af815 100644 --- a/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/ListViewActivity.java @@ -78,10 +78,10 @@ protected void generateData() { double bp = Math.random(); LineAndPointFormatter lpf = new LineAndPointFormatter( - Color.rgb(new Double(rl * 255).intValue(), - new Double(gl * 255).intValue(), new Double(bl * 255).intValue()), - Color.rgb(new Double(rp * 255).intValue(), - new Double(gp * 255).intValue(), new Double(bp * 255).intValue()), + Color.rgb(Double.valueOf(rl * 255).intValue(), + Double.valueOf(gl * 255).intValue(), Double.valueOf(bl * 255).intValue()), + Color.rgb(Double.valueOf(rp * 255).intValue(), + Double.valueOf(gp * 255).intValue(), Double.valueOf(bp * 255).intValue()), null, null); // for fun, configure interpolation on the formatter: diff --git a/demoapp/src/main/java/com/androidplot/demos/SimplePieChartActivity.java b/demoapp/src/main/java/com/androidplot/demos/SimplePieChartActivity.java index 9484176f..cf419083 100644 --- a/demoapp/src/main/java/com/androidplot/demos/SimplePieChartActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/SimplePieChartActivity.java @@ -18,6 +18,7 @@ import android.animation.Animator; import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.*; import android.os.Bundle; @@ -52,6 +53,7 @@ public class SimplePieChartActivity extends Activity private Segment s3; private Segment s4; + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { diff --git a/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java b/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java index c5811bfc..9a8da790 100644 --- a/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java +++ b/demoapp/src/main/java/com/androidplot/demos/TimeSeriesActivity.java @@ -16,6 +16,7 @@ package com.androidplot.demos; +import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Color; import android.graphics.DashPathEffect; @@ -102,6 +103,7 @@ public void onCreate(Bundle savedInstanceState) { // create a simple date format that draws on the year portion of our timestamp. // see http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html // for a full description of SimpleDateFormat. + @SuppressLint("SimpleDateFormat") private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM yyyy"); @Override From b275635276dc9023be0803c2bdc4b2ed516d1053 Mon Sep 17 00:00:00 2001 From: topherbuckley Date: Sun, 19 Sep 2021 02:09:39 +0900 Subject: [PATCH 02/28] Quick start edits (#108) * Changed compile keyword to implementation This is to match updated gradel recommendations * Reordered quickstart guide to avoid unresolved xml file errors Creating the xml files first will remove the unresolved errors you get when copy/pasting the activity code. As people are inherently lazy to read ahead, I think this will eliminate some github issue requests in the future :D --- docs/quickstart.md | 55 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 08abc2dd..18309987 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -14,7 +14,7 @@ To use the library in your gradle project add the following to your build.gradle ```groovy dependencies { - compile "com.androidplot:androidplot-core:1.5.7" + implementation "com.androidplot:androidplot-core:1.5.7" } ``` @@ -55,6 +55,32 @@ directly within your Plot's XML, prefixing each property with "androidPlot". Ex androidPlot.title="My Plot" ``` +Add these files to your **/res/xml** directory: + +#### /res/xml/line_point_formatter_with_labels.xml +```xml + + +``` + +#### /res/xml/line_point_formatter_with_labels_2.xml +```xml + + +``` + # Create an Activity Now let's create an Activity to display the XYPlot we just defined in `simple_xy_plot_example.xml`. The basic steps are: @@ -151,7 +177,6 @@ public class SimpleXYPlotActivity extends Activity { } ``` - One potentially confusing section of the code above are the initializations of LineAndPointFormatter You probably noticed that they take a mysterious reference to an xml resource file. This is actually using [Fig](https://github.com/halfhp/fig) to configure the instance properties from XML. @@ -173,31 +198,5 @@ In general XML configuration should be used over programmatic configuration when more flexibility in terms of defining properties by screen density etc.. For more details on how to programmatically configure Formatters etc. consult the latest Javadocs. -Continuing with the original example above, add these files to your **/res/xml** directory: - -#### /res/xml/line_point_formatter_with_labels.xml -```xml - - -``` - -#### /res/xml/line_point_formatter_with_labels_2.xml -```xml - - -``` - # Whats Next? Learn about [Plot Composition](plot_composition.md) or continue with [XYPlots](xyplot.md). \ No newline at end of file From 6079afc8f18c32efdb9c88b1186cc5300d14f0da Mon Sep 17 00:00:00 2001 From: Nick Fellows Date: Sun, 19 Sep 2021 10:59:43 -0500 Subject: [PATCH 03/28] Project updates (#110) --- .circleci/config.yml | 15 +- README.md | 2 +- androidplot-core/build.gradle | 129 +++++++++--------- .../src/main/java/com/androidplot/Plot.java | 3 +- .../com/androidplot/pie/PieLegendItem.java | 2 +- .../com/androidplot/pie/PieLegendWidget.java | 2 +- .../com/androidplot/ui/PositionMetrics.java | 2 +- .../androidplot/ui/widget/LegendWidget.java | 2 +- .../com/androidplot/ui/widget/Widget.java | 4 +- .../java/com/androidplot/util/FastNumber.java | 4 +- .../xy/FastLineAndPointRenderer.java | 2 +- .../xy/FixedSizeEditableXYSeries.java | 4 +- .../main/java/com/androidplot/xy/PanZoom.java | 2 +- .../com/androidplot/xy/XYConstraints.java | 4 +- .../com/androidplot/xy/XYGraphWidget.java | 4 +- .../java/com/androidplot/xy/XYLegendItem.java | 2 +- .../com/androidplot/xy/XYLegendWidget.java | 2 +- .../main/java/com/androidplot/xy/XYPlot.java | 2 +- .../com/androidplot/ui/widget/WidgetTest.java | 2 +- .../com/androidplot/xy/XYGraphWidgetTest.java | 4 +- build.gradle | 23 +--- demoapp-wearable/build.gradle | 8 +- demoapp/build.gradle | 16 +-- .../demos/AnimatedXYPlotActivity.java | 2 +- .../demos/CandlestickChartActivity.java | 2 +- .../androidplot/demos/DualScaleActivity.java | 2 +- .../androidplot/demos/ListViewActivity.java | 2 +- .../demos/SimpleXYPlotActivity.java | 2 +- .../demos/StepChartExampleActivity.java | 2 +- .../androidplot/demos/TimeSeriesActivity.java | 2 +- docs/quickstart.md | 5 +- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.properties | 2 +- 33 files changed, 124 insertions(+), 139 deletions(-) create mode 100644 gradle.properties diff --git a/.circleci/config.yml b/.circleci/config.yml index f333b5c2..bf60104b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ - - image: circleci/android:api-28-alpha + - image: circleci/android:api-30 working_directory: ~/repo @@ -87,17 +87,10 @@ jobs: path: androidplot-core/build/test-results/ - deploy: - name: "Deploy to Bintray" + name: "Publish" command: | - if [ "${CIRCLE_BRANCH}" == "master" ]; - then ./gradlew bintrayUpload; - fi - - - deploy: - name: "Deploy to Google Play" - command: | - if [ "${CIRCLE_BRANCH}" == "master" ]; + if [ "${CIRCLE_BRANCH}" == "project-updates" ]; then ./misc/download_google_publisher_json.sh; - ./gradlew publishApkRelease + ./gradlew publish; fi \ No newline at end of file diff --git a/README.md b/README.md index 7d7020d2..42b3f9ea 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,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..3d255cc2 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.dicedmelon.gradle.jacoco-android' + id 'maven-publish' + id 'signing' +} class AttrMarkdown extends DefaultTask { @@ -59,8 +61,6 @@ android { compileSdkVersion theCompileSdkVersion defaultConfig { - versionCode theVersionCode - versionName theVersionName minSdkVersion theMinSdkVersion targetSdkVersion theTargetSdkVersion testApplicationId "com.androidplot.test" @@ -70,14 +70,13 @@ android { unitTests.all { jacoco { includeNoLocationClasses = true + jacoco.excludes = ['jdk.internal.*'] } } } - /** - * TODO: enable and address lint issues. - */ lintOptions { + // TODO: enable and address lint issues. abortOnError false } } @@ -90,15 +89,12 @@ def gitUrl = 'https://github.com/halfhp/androidplot.git' dependencies { - implementation 'com.halfhp.fig:figlib:1.0.7' + implementation 'com.halfhp.fig:figlib:1.0.11' 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" - // 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:3.9.0" + testImplementation group: 'junit', name: 'junit', version: '4.13.2' + testImplementation "org.robolectric:robolectric:4.5.1" } task javadoc(type: Javadoc) { @@ -123,63 +119,70 @@ task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs } -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' - } - } - developers { - developer { - id 'halfhp' - name 'Nick Fellows' - email 'halfhp@gmail.com' - } - } - scm { - connection gitUrl - developerConnection gitUrl - url siteUrl +javadoc { + options.overview = "src/main/java/overview.html" +} +afterEvaluate { + publishing { + repositories { + maven { + name = "Maven Central" + url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + credentials { + username = System.getenv("OSSRH_ACTOR") + password = System.getenv("OSSRH_TOKEN") } } } - } -} - -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') + publications { + release(MavenPublication) { + + from components.release + + // You can then customize attributes of the publication as shown below. + groupId = 'com.androidplot' + artifactId = 'androidplot' + 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' + } + } + scm { + connection = gitUrl + developerConnection = gitUrl + url = gitUrl - 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" +afterEvaluate { + signing { + def signingKey = System.getenv("SIGNING_KEY") + def signingPassword = System.getenv("SIGNING_PASSWORD") + useInMemoryPgpKeys(signingKey, signingPassword) + sign publishing.publications.release + } } artifacts { diff --git a/androidplot-core/src/main/java/com/androidplot/Plot.java b/androidplot-core/src/main/java/com/androidplot/Plot.java index 47ef0fd6..925a9c78 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; 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..4f6fa04a 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; 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/test/java/com/androidplot/ui/widget/WidgetTest.java b/androidplot-core/src/test/java/com/androidplot/ui/widget/WidgetTest.java index 408edc33..ce398dc9 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; 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..5a0da878 100644 --- a/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java +++ b/androidplot-core/src/test/java/com/androidplot/xy/XYGraphWidgetTest.java @@ -298,10 +298,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); diff --git a/build.gradle b/build.gradle index a00c8e72..96bd5758 100644 --- a/build.gradle +++ b/build.gradle @@ -14,34 +14,25 @@ * limitations under the License. */ -apply plugin: 'java' - -allprojects { - repositories { - jcenter() - } -} - ext { - theCompileSdkVersion = 28 - theTargetSdkVersion = 28 + theCompileSdkVersion = 30 + theTargetSdkVersion = 30 theMinSdkVersion = 5 - theVersionName = '1.5.7' + theVersionName = '1.5.8' theVersionCode = 1 + gitUrl = 'https://github.com/halfhp/androidplot.git' } buildscript { repositories { mavenCentral() - jcenter() + 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:7.0.2' + classpath 'com.dicedmelon.gradle:jacoco-android:0.1.5-SNAPSHOT' } } diff --git a/demoapp-wearable/build.gradle b/demoapp-wearable/build.gradle index 22e5186d..3bfc0ee0 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 diff --git a/demoapp/build.gradle b/demoapp/build.gradle index 191280a5..a5583eb9 100644 --- a/demoapp/build.gradle +++ b/demoapp/build.gradle @@ -14,22 +14,19 @@ * limitations under the License. */ -//apply plugin: 'com.android.application' -//apply plugin: 'com.github.triplet.play' - buildscript { repositories { mavenCentral() } dependencies { - classpath 'com.github.triplet.gradle:play-publisher:2.2.1' + classpath 'com.github.triplet.gradle:play-publisher:3.6.0' } } plugins { id 'com.android.application' - id 'com.github.triplet.play' version '2.2.1' + id 'com.github.triplet.play' version '3.6.0' } dependencies { @@ -37,7 +34,9 @@ dependencies { implementation 'com.crittercism:crittercism-android-agent:5.4.0' 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' } @@ -72,17 +71,14 @@ android { } } - - /** - * TODO: uncomment this and address all the lint issues. - */ lintOptions { + // TODO: set to true and address all the lint issues. abortOnError false } } 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' } 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/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/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/docs/quickstart.md b/docs/quickstart.md index 18309987..2f1853d2 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -14,10 +14,13 @@ To use the library in your gradle project add the following to your build.gradle ```groovy dependencies { - implementation "com.androidplot:androidplot-core:1.5.7" + implementation "com.androidplot:androidplot-core:1.5.8" } ``` +*NOTE: As of version 1.5.8 Androidplot has migrated over from the Android Support Libraries to androidx. +If you have a very old project and experience issues, may need to stay on version 1.5.7* + If you’re using Proguard obfuscation (Projects created by Android Studio do by default) you’ll also want add this to your proguard-rules.pro file: diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..d015431a --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b37f1ae6..0a24689e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip From 44042626cefab91712dcbb923af2332f6438affe Mon Sep 17 00:00:00 2001 From: Nick Fellows Date: Sun, 19 Sep 2021 17:19:54 -0500 Subject: [PATCH 04/28] render mode attrs should have a distinct ordinal value (#111) --- .../src/main/java/com/androidplot/Plot.java | 22 +++++++++---------- .../src/main/res/values/attrs.xml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/androidplot-core/src/main/java/com/androidplot/Plot.java b/androidplot-core/src/main/java/com/androidplot/Plot.java index 925a9c78..ac2d6a09 100644 --- a/androidplot-core/src/main/java/com/androidplot/Plot.java +++ b/androidplot-core/src/main/java/com/androidplot/Plot.java @@ -145,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(); 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: - + From b365c634ad994386c85440d656e69071870a8beb Mon Sep 17 00:00:00 2001 From: Nick Fellows Date: Sun, 19 Sep 2021 17:29:06 -0500 Subject: [PATCH 05/28] fix androidplot artifact coordinates (#112) --- androidplot-core/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/androidplot-core/build.gradle b/androidplot-core/build.gradle index 3d255cc2..e81e40a2 100644 --- a/androidplot-core/build.gradle +++ b/androidplot-core/build.gradle @@ -143,7 +143,7 @@ afterEvaluate { // You can then customize attributes of the publication as shown below. groupId = 'com.androidplot' - artifactId = 'androidplot' + artifactId = 'androidplot-core' version = theVersionName pom { From 0a2e28251a4458a3486db4da0a4e2f856d07a7bb Mon Sep 17 00:00:00 2001 From: Nick Fellows Date: Sun, 19 Sep 2021 18:05:52 -0500 Subject: [PATCH 06/28] #104 - Add support for redrawing plots inside recyclerview + example (#113) --- .../src/main/java/com/androidplot/Plot.java | 86 +++++--- demoapp/build.gradle | 15 +- demoapp/src/main/AndroidManifest.xml | 1 + .../com/androidplot/demos/MainActivity.java | 193 ------------------ .../com/androidplot/demos/MainActivity.kt | 122 +++++++++++ .../androidplot/demos/RecyclerViewActivity.kt | 130 ++++++++++++ demoapp/src/main/res/layout/main.xml | 7 + .../main/res/layout/recyclerview_example.xml | 31 +++ .../res/layout/recyclerview_example_item.xml | 25 +++ docs/quickstart.md | 2 +- docs/release_notes.md | 7 + 11 files changed, 397 insertions(+), 222 deletions(-) delete mode 100644 demoapp/src/main/java/com/androidplot/demos/MainActivity.java create mode 100644 demoapp/src/main/java/com/androidplot/demos/MainActivity.kt create mode 100644 demoapp/src/main/java/com/androidplot/demos/RecyclerViewActivity.kt create mode 100644 demoapp/src/main/res/layout/recyclerview_example.xml create mode 100644 demoapp/src/main/res/layout/recyclerview_example_item.xml diff --git a/androidplot-core/src/main/java/com/androidplot/Plot.java b/androidplot-core/src/main/java/com/androidplot/Plot.java index ac2d6a09..63d2e831 100644 --- a/androidplot-core/src/main/java/com/androidplot/Plot.java +++ b/androidplot-core/src/main/java/com/androidplot/Plot.java @@ -212,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(); @@ -226,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); @@ -408,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"); } /** @@ -745,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? @@ -778,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/demoapp/build.gradle b/demoapp/build.gradle index a5583eb9..b8b76251 100644 --- a/demoapp/build.gradle +++ b/demoapp/build.gradle @@ -15,12 +15,13 @@ */ buildscript { - + ext.kotlin_version = '1.5.31' repositories { mavenCentral() } dependencies { classpath 'com.github.triplet.gradle:play-publisher:3.6.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -29,9 +30,14 @@ plugins { id 'com.github.triplet.play' version '3.6.0' } +apply plugin: 'kotlin-android' + dependencies { + implementation "androidx.core:core-ktx:1.6.0" + 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.2.1' debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3' @@ -43,6 +49,10 @@ dependencies { android { compileSdkVersion theCompileSdkVersion + buildFeatures { + viewBinding true + } + defaultConfig { versionCode theVersionCode versionName theVersionName @@ -82,3 +92,6 @@ play { serviceAccountCredentials.set(file(System.getenv("PUBLISHER_ACCT_JSON_FILE") ?: "publisher.json")) track = 'beta' } +repositories { + mavenCentral() +} diff --git a/demoapp/src/main/AndroidManifest.xml b/demoapp/src/main/AndroidManifest.xml index 89f1428f..16245b9f 100644 --- a/demoapp/src/main/AndroidManifest.xml +++ b/demoapp/src/main/AndroidManifest.xml @@ -95,6 +95,7 @@ + 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..6c8320e1 --- /dev/null +++ b/demoapp/src/main/java/com/androidplot/demos/MainActivity.kt @@ -0,0 +1,122 @@ +/* + * 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 com.crittercism.app.Crittercism +import android.content.Intent +import android.util.Log +import com.androidplot.demos.databinding.MainBinding + +class MainActivity : Activity() { + + private lateinit var binding: MainBinding + + companion object { + private val TAG = MainActivity::class.java.name + + // DO *NOT* CHANGE THIS LINE! (CI-MATCH-POPULATE) + private val CRITTERCISM_APP_ID: String? = null + } + + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = MainBinding.inflate(layoutInflater) + if (CRITTERCISM_APP_ID != null) { + Log.d(TAG, "Crittercism initialized.") + Crittercism.initialize(applicationContext, CRITTERCISM_APP_ID) + } + + 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/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"/> +