From 3456aef5c3c6faeb71155a281c0f15bd7f03fcbb Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 14:40:40 +0000 Subject: [PATCH 01/15] Prepare 1.0-SNAPSHOT --- README.md | 4 ++-- gradle.properties | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5f94f58..04a3cf9 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The rangeseekbar-sample shows the available features and customizations in code ```groovy dependencies { - compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:0.3.0' + compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:0.4.0' } ``` @@ -49,7 +49,7 @@ The rangeseekbar-sample shows the available features and customizations in code ```groovy dependencies { - compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:0.4.0-SNAPSHOT' + compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:1.4.0-SNAPSHOT' } ``` diff --git a/gradle.properties b/gradle.properties index c04991e..94561cf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,9 +16,8 @@ # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true - -VERSION_NAME=0.4.0 -VERSION_CODE=004000 +VERSION_NAME=1.0.0-SNAPSHOT +VERSION_CODE=100000 GROUP=org.florescu.android.rangeseekbar SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots From c4ee37d18a30a86ebc360684c42e051283f661cd Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 15:08:19 +0000 Subject: [PATCH 02/15] Updates and cleanup --- build.gradle | 4 +-- gradle/wrapper/gradle-wrapper.properties | 4 +-- rangeseekbar-sample/build.gradle | 9 ++--- rangeseekbar/build.gradle | 33 +++++++------------ .../rangeseekbar/RangeSeekBarTest.java | 4 +-- 5 files changed, 22 insertions(+), 32 deletions(-) diff --git a/build.gradle b/build.gradle index dfe5c8f..e681e9b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0' - classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0' + classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.github.ben-manes:gradle-versions-plugin:0.13.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 83e1d30..69dcfcf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu May 26 16:38:46 BST 2016 +#Fri Nov 25 14:42:07 GMT 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/rangeseekbar-sample/build.gradle b/rangeseekbar-sample/build.gradle index 4fd63f7..463963d 100644 --- a/rangeseekbar-sample/build.gradle +++ b/rangeseekbar-sample/build.gradle @@ -6,16 +6,17 @@ repositories { } android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.0" defaultConfig { applicationId "org.florescu.android.rangeseekbar.sample" minSdkVersion 15 - targetSdkVersion 23 + targetSdkVersion 25 versionCode 1 versionName "1.0" } + buildTypes { release { minifyEnabled false @@ -26,6 +27,6 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.4.0' + compile 'com.android.support:appcompat-v7:25.0.1' compile project(':rangeseekbar') } diff --git a/rangeseekbar/build.gradle b/rangeseekbar/build.gradle index 67fd780..e5465c3 100644 --- a/rangeseekbar/build.gradle +++ b/rangeseekbar/build.gradle @@ -1,22 +1,12 @@ -buildscript { - repositories { - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:2.1.0' - } -} - apply plugin: 'com.android.library' android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.0" defaultConfig { minSdkVersion 15 - targetSdkVersion 23 + targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -27,21 +17,20 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - android.sourceSets.test.java.srcDirs += "build/generated/source/r/debug" } dependencies { - repositories { - mavenCentral() - } - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.4.0' - compile 'com.android.support:support-annotations:23.4.0' + compile 'com.android.support:support-annotations:25.0.1' // Robolectric - testCompile 'org.robolectric:robolectric:3.1-rc1' - testCompile "org.mockito:mockito-core:2.0.53-beta" + testCompile 'org.robolectric:robolectric:3.1.4' + testCompile "org.mockito:mockito-core:2.2.23" + testCompile 'junit:junit:4.12' + testCompile('com.squareup.assertj:assertj-android:1.1.1') { + exclude group: 'com.android.support', module: 'support-annotations' + } + } apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle' \ No newline at end of file diff --git a/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java b/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java index ce0f2a5..3d8b488 100644 --- a/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java +++ b/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java @@ -3,11 +3,11 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -@RunWith(RobolectricGradleTestRunner.class) +@RunWith(RobolectricTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class RangeSeekBarTest { From 320e39771f27df4864da527df07a0e150c153c89 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 15:13:43 +0000 Subject: [PATCH 03/15] Cleanup util classes --- .../java/org/florescu/android/util/BitmapUtil.java | 7 ++++++- .../java/org/florescu/android/util/PixelUtil.java | 11 +++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rangeseekbar/src/main/java/org/florescu/android/util/BitmapUtil.java b/rangeseekbar/src/main/java/org/florescu/android/util/BitmapUtil.java index d01faa3..81022cb 100644 --- a/rangeseekbar/src/main/java/org/florescu/android/util/BitmapUtil.java +++ b/rangeseekbar/src/main/java/org/florescu/android/util/BitmapUtil.java @@ -5,7 +5,12 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -public class BitmapUtil { +public final class BitmapUtil { + + private BitmapUtil() { + throw new AssertionError("Don't instantiate me"); + } + public static Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); diff --git a/rangeseekbar/src/main/java/org/florescu/android/util/PixelUtil.java b/rangeseekbar/src/main/java/org/florescu/android/util/PixelUtil.java index 0af431a..d07a934 100644 --- a/rangeseekbar/src/main/java/org/florescu/android/util/PixelUtil.java +++ b/rangeseekbar/src/main/java/org/florescu/android/util/PixelUtil.java @@ -23,19 +23,14 @@ /** * Util class for converting between dp, px and other magical pixel units */ -public class PixelUtil { +public final class PixelUtil { private PixelUtil() { + throw new AssertionError("Don't instantiate me"); } public static int dpToPx(Context context, int dp) { - int px = Math.round(dp * getPixelScaleFactor(context)); - return px; - } - - public static int pxToDp(Context context, int px) { - int dp = Math.round(px / getPixelScaleFactor(context)); - return dp; + return Math.round(dp * getPixelScaleFactor(context)); } private static float getPixelScaleFactor(Context context) { From 2fc1d9cfd7397a437a6495742a6c1823f18780a1 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 15:39:36 +0000 Subject: [PATCH 04/15] Clear the crazy generics --- .../rangeseekbar/sample/DemoActivity.java | 3 +- .../src/main/res/layout/main.xml | 20 +-- .../android/rangeseekbar/RangeSeekBar.java | 146 ++++++------------ .../rangeseekbar/RangeSeekBarTest.java | 13 -- 4 files changed, 57 insertions(+), 125 deletions(-) diff --git a/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java b/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java index 29162fd..bf1b95c 100644 --- a/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java +++ b/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java @@ -20,7 +20,6 @@ import android.app.Activity; import android.os.Bundle; import android.widget.FrameLayout; -import android.widget.LinearLayout; import org.florescu.android.rangeseekbar.RangeSeekBar; @@ -35,7 +34,7 @@ public void onCreate(Bundle savedInstanceState) { setContentView(R.layout.main); // Setup the new range seek bar - RangeSeekBar rangeSeekBar = new RangeSeekBar<>(this); + RangeSeekBar rangeSeekBar = new RangeSeekBar(this); // Set the range rangeSeekBar.setRangeValues(15, 90); rangeSeekBar.setSelectedMinValue(20); diff --git a/rangeseekbar-sample/src/main/res/layout/main.xml b/rangeseekbar-sample/src/main/res/layout/main.xml index 69fb5f7..a2c1774 100644 --- a/rangeseekbar-sample/src/main/res/layout/main.xml +++ b/rangeseekbar-sample/src/main/res/layout/main.xml @@ -8,6 +8,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:background="#263238" android:padding="8dp"> - + + + + + - + + + + + + * The range value types can be any {@link Number}.
*
* Improved {@link android.view.MotionEvent} handling for smoother use, anti-aliased painting for improved aesthetics. * - * @param The Number type of the range values. One of Long, Double, Integer, Float, Short, Byte or BigDecimal. * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) * @author Peter Sinnott (psinnott@gmail.com) * @author Thomas Barrasso (tbarrasso@sevenplusandroid.org) * @author Alex Florescu (alex@florescu.org) * @author Michael Keppler (bananeweizen@gmx.de) */ -public class RangeSeekBar extends ImageView { +public class RangeSeekBar extends ImageView { /** * Default color of a {@link RangeSeekBar}, #FF33B5E5. This is also known as "Ice Cream Sandwich" blue. */ @@ -95,15 +94,14 @@ public class RangeSeekBar extends ImageView { private float thumbHalfHeight; private float padding; - protected T absoluteMinValue, absoluteMaxValue, absoluteStepValue; - protected NumberType numberType; + protected int absoluteMinValue, absoluteMaxValue, absoluteStepValue; protected double absoluteMinValuePrim, absoluteMaxValuePrim, absoluteStepValuePrim; protected double normalizedMinValue = 0d; protected double normalizedMaxValue = 1d; protected double minDeltaForDefault = 0; private Thumb pressedThumb = null; private boolean notifyWhileDragging = false; - private OnRangeSeekBarChangeListener listener; + private OnRangeSeekBarChangeListener listener; private float downMotionX; @@ -153,19 +151,19 @@ public RangeSeekBar(Context context, AttributeSet attrs, int defStyle) { init(context, attrs); } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public RangeSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + } + @SuppressWarnings("unchecked") - private T extractNumericValueFromAttributes(TypedArray a, int attribute, int defaultValue) { + private int extractNumericValueFromAttributes(TypedArray a, int attribute, int defaultValue) { TypedValue tv = a.peekValue(attribute); if (tv == null) { - return (T) Integer.valueOf(defaultValue); - } - - int type = tv.type; - if (type == TypedValue.TYPE_FLOAT) { - return (T) Float.valueOf(a.getFloat(attribute, defaultValue)); - } else { - return (T) Integer.valueOf(a.getInteger(attribute, defaultValue)); + return defaultValue; } + return a.getInteger(attribute, defaultValue); } private void init(Context context, AttributeSet attrs) { @@ -278,13 +276,13 @@ private void init(Context context, AttributeSet attrs) { } } - public void setRangeValues(T minValue, T maxValue) { + public void setRangeValues(int minValue, int maxValue) { this.absoluteMinValue = minValue; this.absoluteMaxValue = maxValue; setValuePrimAndNumberType(); } - public void setRangeValues(T minValue, T maxValue, T step) { + public void setRangeValues(int minValue, int maxValue, int step) { this.absoluteStepValue = step; setRangeValues(minValue, maxValue); } @@ -295,23 +293,23 @@ public void setTextAboveThumbsColor(int textAboveThumbsColor) { } public void setTextAboveThumbsColorResource(@ColorRes int resId) { - setTextAboveThumbsColor(getResources().getColor(resId)); + setTextAboveThumbsColor(// TODO looks like you would need contextcompat here + getResources().getColor(resId)); } @SuppressWarnings("unchecked") // only used to set default values when initialised from XML without any values specified private void setRangeToDefaultValues() { - this.absoluteMinValue = (T) DEFAULT_MINIMUM; - this.absoluteMaxValue = (T) DEFAULT_MAXIMUM; - this.absoluteStepValue = (T) DEFAULT_STEP; + this.absoluteMinValue = DEFAULT_MINIMUM; + this.absoluteMaxValue = DEFAULT_MAXIMUM; + this.absoluteStepValue = DEFAULT_STEP; setValuePrimAndNumberType(); } private void setValuePrimAndNumberType() { - absoluteMinValuePrim = absoluteMinValue.doubleValue(); - absoluteMaxValuePrim = absoluteMaxValue.doubleValue(); - absoluteStepValuePrim = absoluteStepValue.doubleValue(); - numberType = NumberType.fromNumber(absoluteMinValue); + absoluteMinValuePrim = absoluteMinValue; + absoluteMaxValuePrim = absoluteMaxValue; + absoluteStepValuePrim = absoluteStepValue; } @SuppressWarnings("unused") @@ -338,7 +336,7 @@ public void setNotifyWhileDragging(boolean flag) { * * @return The absolute minimum value of the range. */ - public T getAbsoluteMinValue() { + public int getAbsoluteMinValue() { return absoluteMinValue; } @@ -347,7 +345,7 @@ public T getAbsoluteMinValue() { * * @return The absolute maximum value of the range. */ - public T getAbsoluteMaxValue() { + public int getAbsoluteMaxValue() { return absoluteMaxValue; } @@ -357,9 +355,9 @@ public T getAbsoluteMaxValue() { * @return rounded off value */ @SuppressWarnings("unchecked") - private T roundOffValueToStep(T value) { - double d = Math.round(value.doubleValue() / absoluteStepValuePrim) * absoluteStepValuePrim; - return (T) numberType.toNumber(Math.max(absoluteMinValuePrim, Math.min(absoluteMaxValuePrim, d))); + private int roundOffValueToStep(int value) { + double d = Math.round(value / absoluteStepValuePrim) * absoluteStepValuePrim; + return (int) Math.max(absoluteMinValuePrim, Math.min(absoluteMaxValuePrim, d)); } /** @@ -367,7 +365,7 @@ private T roundOffValueToStep(T value) { * * @return The currently selected min value. */ - public T getSelectedMinValue() { + public int getSelectedMinValue() { return roundOffValueToStep(normalizedToValue(normalizedMinValue)); } @@ -380,7 +378,7 @@ public boolean isDragging() { * * @param value The Number value to set the minimum value to. Will be clamped to given absolute minimum/maximum range. */ - public void setSelectedMinValue(T value) { + public void setSelectedMinValue(int value) { // in case absoluteMinValue == absoluteMaxValue, avoid division by zero when normalizing. if (0 == (absoluteMaxValuePrim - absoluteMinValuePrim)) { setNormalizedMinValue(0d); @@ -394,7 +392,7 @@ public void setSelectedMinValue(T value) { * * @return The currently selected max value. */ - public T getSelectedMaxValue() { + public int getSelectedMaxValue() { return roundOffValueToStep(normalizedToValue(normalizedMaxValue)); } @@ -403,7 +401,7 @@ public T getSelectedMaxValue() { * * @param value The Number value to set the maximum value to. Will be clamped to given absolute minimum/maximum range. */ - public void setSelectedMaxValue(T value) { + public void setSelectedMaxValue(int value) { // in case absoluteMinValue == absoluteMaxValue, avoid division by zero when normalizing. if (0 == (absoluteMaxValuePrim - absoluteMinValuePrim)) { setNormalizedMaxValue(1d); @@ -418,7 +416,7 @@ public void setSelectedMaxValue(T value) { * @param listener The listener to notify about changed selected values. */ @SuppressWarnings("unused") - public void setOnRangeSeekBarChangeListener(OnRangeSeekBarChangeListener listener) { + public void setOnRangeSeekBarChangeListener(OnRangeSeekBarChangeListener listener) { this.listener = listener; } @@ -698,7 +696,8 @@ protected synchronized void onDraw(@NonNull Canvas canvas) { } - protected String valueToString(T value) { + // TODO maaaaybe make this private and add formatter? + protected String valueToString(int value) { return String.valueOf(value); } @@ -814,10 +813,10 @@ private void setNormalizedMaxValue(double value) { * Converts a normalized value to a Number object in the value space between absolute minimum and maximum. */ @SuppressWarnings("unchecked") - protected T normalizedToValue(double normalized) { + protected int normalizedToValue(double normalized) { double v = absoluteMinValuePrim + normalized * (absoluteMaxValuePrim - absoluteMinValuePrim); // TODO parameterize this rounding to allow variable decimal points - return (T) numberType.toNumber(Math.round(v * 100) / 100d); + return (int) (Math.round(v * 100) / 100d); } /** @@ -826,12 +825,12 @@ protected T normalizedToValue(double normalized) { * @param value The Number value to normalize. * @return The normalized double. */ - protected double valueToNormalized(T value) { + protected double valueToNormalized(int value) { if (0 == absoluteMaxValuePrim - absoluteMinValuePrim) { // prevent division by zero, simply return 0. return 0d; } - return (value.doubleValue() - absoluteMinValuePrim) / (absoluteMaxValuePrim - absoluteMinValuePrim); + return (value - absoluteMinValuePrim) / (absoluteMaxValuePrim - absoluteMinValuePrim); } /** @@ -868,69 +867,14 @@ private enum Thumb { MIN, MAX } - /** - * Utility enumeration used to convert between Numbers and doubles. - * - * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) - */ - protected enum NumberType { - LONG, DOUBLE, INTEGER, FLOAT, SHORT, BYTE, BIG_DECIMAL; - - public static NumberType fromNumber(E value) throws IllegalArgumentException { - if (value instanceof Long) { - return LONG; - } - if (value instanceof Double) { - return DOUBLE; - } - if (value instanceof Integer) { - return INTEGER; - } - if (value instanceof Float) { - return FLOAT; - } - if (value instanceof Short) { - return SHORT; - } - if (value instanceof Byte) { - return BYTE; - } - if (value instanceof BigDecimal) { - return BIG_DECIMAL; - } - throw new IllegalArgumentException("Number class '" + value.getClass().getName() + "' is not supported"); - } - - public Number toNumber(double value) { - switch (this) { - case LONG: - return (long) value; - case DOUBLE: - return value; - case INTEGER: - return (int) value; - case FLOAT: - return (float) value; - case SHORT: - return (short) value; - case BYTE: - return (byte) value; - case BIG_DECIMAL: - return BigDecimal.valueOf(value); - } - throw new InstantiationError("can't convert " + this + " to a Number object"); - } - } - /** * Callback listener interface to notify about changed range values. - * - * @param The Number type the RangeSeekBar has been declared with. - * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) */ - public interface OnRangeSeekBarChangeListener { + public interface OnRangeSeekBarChangeListener { + + void onRangeSeekBarValuesChanged(RangeSeekBar bar, int selectedMinValue, int selectedMaxValue); - void onRangeSeekBarValuesChanged(RangeSeekBar bar, T minValue, T maxValue); + // TODO add onStartTrackingTouch and onStopTrackingTouch } } diff --git a/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java b/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java index 3d8b488..0d0583c 100644 --- a/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java +++ b/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java @@ -1,25 +1,12 @@ package org.florescu.android.rangeseekbar; -import org.junit.Assert; -import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class RangeSeekBarTest { - @Test - public void rsb_should_handle_long_values() { - RangeSeekBar mSeekBar = new RangeSeekBar<>(RuntimeEnvironment.application); - // Set up the seek bar - mSeekBar.setRangeValues(0L, 100L); - long minValue = mSeekBar.getAbsoluteMinValue(); - Assert.assertEquals(0L, minValue); - long maxValue = mSeekBar.getAbsoluteMaxValue(); - Assert.assertEquals(100L, maxValue); - } } \ No newline at end of file From 6273a16668ff013ef7893367738a728c49ddefa2 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 15:56:36 +0000 Subject: [PATCH 05/15] Readd appcompat, we need some stuff --- rangeseekbar/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rangeseekbar/build.gradle b/rangeseekbar/build.gradle index e5465c3..e7d1c83 100644 --- a/rangeseekbar/build.gradle +++ b/rangeseekbar/build.gradle @@ -21,7 +21,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:support-annotations:25.0.1' + compile 'com.android.support:support-compat:25.0.1' // Robolectric testCompile 'org.robolectric:robolectric:3.1.4' From a7b95232aecfd693abd1f140ec0fb40776a33bd4 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 15:56:48 +0000 Subject: [PATCH 06/15] API, API, API --- .../android/rangeseekbar/RangeSeekBar.java | 98 +++++++++++-------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java b/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java index ab87033..00372a5 100644 --- a/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java +++ b/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java @@ -34,8 +34,10 @@ import android.os.Build; import android.os.Bundle; import android.os.Parcelable; +import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.util.TypedValue; import android.view.MotionEvent; @@ -47,7 +49,7 @@ /** * Widget that lets users select a minimum and maximum value on a given numerical range. - * The range value types can be any {@link Number}.
+ * The range value types can be any {@link Number}.
// TODO get rid of all number references *
* Improved {@link android.view.MotionEvent} handling for smoother use, anti-aliased painting for improved aesthetics. * @@ -61,21 +63,21 @@ public class RangeSeekBar extends ImageView { /** * Default color of a {@link RangeSeekBar}, #FF33B5E5. This is also known as "Ice Cream Sandwich" blue. */ - public static final int ACTIVE_COLOR = Color.argb(0xFF, 0x33, 0xB5, 0xE5); + private static final int ACTIVE_COLOR = Color.argb(0xFF, 0x33, 0xB5, 0xE5); /** * An invalid pointer id. */ - public static final int INVALID_POINTER_ID = 255; + private static final int INVALID_POINTER_ID = 255; // Localized constants from MotionEvent for compatibility // with API < 8 "Froyo". - public static final int ACTION_POINTER_INDEX_MASK = 0x0000ff00, ACTION_POINTER_INDEX_SHIFT = 8; + private static final int ACTION_POINTER_INDEX_MASK = 0x0000ff00, ACTION_POINTER_INDEX_SHIFT = 8; - public static final Integer DEFAULT_MINIMUM = 0; - public static final Integer DEFAULT_MAXIMUM = 100; - public static final Integer DEFAULT_STEP = 1; - public static final int HEIGHT_IN_DP = 30; - public static final int TEXT_LATERAL_PADDING_IN_DP = 3; + private static final Integer DEFAULT_MINIMUM = 0; + private static final Integer DEFAULT_MAXIMUM = 100; + private static final Integer DEFAULT_STEP = 1; + private static final int HEIGHT_IN_DP = 30; + private static final int TEXT_LATERAL_PADDING_IN_DP = 3; private static final int INITIAL_PADDING_IN_DP = 8; private static final int DEFAULT_TEXT_SIZE_IN_DP = 14; @@ -94,11 +96,11 @@ public class RangeSeekBar extends ImageView { private float thumbHalfHeight; private float padding; - protected int absoluteMinValue, absoluteMaxValue, absoluteStepValue; - protected double absoluteMinValuePrim, absoluteMaxValuePrim, absoluteStepValuePrim; - protected double normalizedMinValue = 0d; - protected double normalizedMaxValue = 1d; - protected double minDeltaForDefault = 0; + private int absoluteMinValue, absoluteMaxValue, absoluteStepValue; + private double absoluteMinValuePrim, absoluteMaxValuePrim, absoluteStepValuePrim; + private double normalizedMinValue = 0d; + private double normalizedMaxValue = 1d; + private double minDeltaForDefault = 0; private Thumb pressedThumb = null; private boolean notifyWhileDragging = false; private OnRangeSeekBarChangeListener listener; @@ -123,6 +125,7 @@ public class RangeSeekBar extends ImageView { private float internalPad; private int activeColor; private int defaultColor; + @ColorInt private int textAboveThumbsColor; private boolean thumbShadow; @@ -287,14 +290,14 @@ public void setRangeValues(int minValue, int maxValue, int step) { setRangeValues(minValue, maxValue); } - public void setTextAboveThumbsColor(int textAboveThumbsColor) { + // TODO should this be just @ColorRes + public void setTextAboveThumbsColor(@ColorInt int textAboveThumbsColor) { this.textAboveThumbsColor = textAboveThumbsColor; invalidate(); } public void setTextAboveThumbsColorResource(@ColorRes int resId) { - setTextAboveThumbsColor(// TODO looks like you would need contextcompat here - getResources().getColor(resId)); + setTextAboveThumbsColor(ContextCompat.getColor(getContext(), resId)); } @SuppressWarnings("unchecked") @@ -312,7 +315,7 @@ private void setValuePrimAndNumberType() { absoluteStepValuePrim = absoluteStepValue; } - @SuppressWarnings("unused") + @SuppressWarnings("unused") // we're a library public void resetSelectedValues() { setSelectedMinValue(absoluteMinValue); setSelectedMaxValue(absoluteMaxValue); @@ -420,24 +423,11 @@ public void setOnRangeSeekBarChangeListener(OnRangeSeekBarChangeListener listene this.listener = listener; } - /** - * Set the path that defines the shadow of the thumb. This path should be defined assuming - * that the center of the shadow is at the top left corner (0,0) of the canvas. The - * {@link #drawThumbShadow(float, Canvas)} method will place the shadow appropriately. - * - * @param thumbShadowPath The path defining the thumb shadow - */ - @SuppressWarnings("unused") - public void setThumbShadowPath(Path thumbShadowPath) { - this.thumbShadowPath = thumbShadowPath; - } - /** * Handles thumb selection and movement. Notifies listener callback on certain events. */ @Override public boolean onTouchEvent(@NonNull MotionEvent event) { - if (!isEnabled()) { return false; } @@ -570,15 +560,21 @@ private void attemptClaimDrag() { /** * This is called when the user has started touching this widget. */ - void onStartTrackingTouch() { + private void onStartTrackingTouch() { isDragging = true; + if (listener != null) { + listener.onStartTrackingTouch(this); + } } /** * This is called when the user either releases his touch or the touch is canceled. */ - void onStopTrackingTouch() { + private void onStopTrackingTouch() { isDragging = false; + if (listener != null) { + listener.onStopTrackingTouch(this); + } } /** @@ -697,7 +693,7 @@ protected synchronized void onDraw(@NonNull Canvas canvas) { } // TODO maaaaybe make this private and add formatter? - protected String valueToString(int value) { + private String valueToString(int value) { return String.valueOf(value); } @@ -705,6 +701,7 @@ protected String valueToString(int value) { * Overridden to save instance state when device orientation changes. This method is called automatically if you assign an id to the RangeSeekBar widget using the {@link #setId(int)} method. Other members of this class than the normalized min and max values don't need to be saved. */ @Override + // TODO test these protected Parcelable onSaveInstanceState() { final Bundle bundle = new Bundle(); bundle.putParcelable("SUPER", super.onSaveInstanceState()); @@ -813,7 +810,7 @@ private void setNormalizedMaxValue(double value) { * Converts a normalized value to a Number object in the value space between absolute minimum and maximum. */ @SuppressWarnings("unchecked") - protected int normalizedToValue(double normalized) { + private int normalizedToValue(double normalized) { double v = absoluteMinValuePrim + normalized * (absoluteMaxValuePrim - absoluteMinValuePrim); // TODO parameterize this rounding to allow variable decimal points return (int) (Math.round(v * 100) / 100d); @@ -825,7 +822,7 @@ protected int normalizedToValue(double normalized) { * @param value The Number value to normalize. * @return The normalized double. */ - protected double valueToNormalized(int value) { + private double valueToNormalized(int value) { if (0 == absoluteMaxValuePrim - absoluteMinValuePrim) { // prevent division by zero, simply return 0. return 0d; @@ -870,11 +867,34 @@ private enum Thumb { /** * Callback listener interface to notify about changed range values. */ + // TODO should we add fromUser public interface OnRangeSeekBarChangeListener { - void onRangeSeekBarValuesChanged(RangeSeekBar bar, int selectedMinValue, int selectedMaxValue); - - // TODO add onStartTrackingTouch and onStopTrackingTouch + /** + * Notification that the progress level has changed. Clients can use the fromUser parameter + * to distinguish user-initiated changes from those that occurred programmatically. + * + * @param rangeSeekBar The RangeSeekBar whose progress has changed + * @param selectedMinValue The current value selected by the left/minimum thumb. + * @param selectedMaxValue The current value selected by the right/maximum thumb. + */ + void onRangeSeekBarValuesChanged(RangeSeekBar rangeSeekBar, int selectedMinValue, int selectedMaxValue); + + /** + * Notification that the user has started a touch gesture. Clients may want to use this + * to disable advancing the seekbar. + * + * @param rangeSeekBar The RangeSeekBar in which the touch gesture began + */ + void onStartTrackingTouch(RangeSeekBar rangeSeekBar); + + /** + * Notification that the user has finished a touch gesture. Clients may want to use this + * to re-enable advancing the seekbar. + * + * @param rangeSeekBar The RangeSeekBar in which the touch gesture began + */ + void onStopTrackingTouch(RangeSeekBar rangeSeekBar); } } From b07cf22b60c208df5143881b0cfe10e7f91323f2 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 16:31:08 +0000 Subject: [PATCH 07/15] Text formatter --- .../rangeseekbar/sample/DemoActivity.java | 6 +++ .../android/rangeseekbar/RangeSeekBar.java | 46 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java b/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java index bf1b95c..889c794 100644 --- a/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java +++ b/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java @@ -39,6 +39,12 @@ public void onCreate(Bundle savedInstanceState) { rangeSeekBar.setRangeValues(15, 90); rangeSeekBar.setSelectedMinValue(20); rangeSeekBar.setSelectedMaxValue(88); + rangeSeekBar.setTextFormatter(new RangeSeekBar.TextFormatter() { + @Override + public String formatValue(int value) { + return value + " kittens"; + } + }); // Add to layout FrameLayout layout = (FrameLayout) findViewById(R.id.seekbar_placeholder); diff --git a/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java b/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java index 00372a5..8a47573 100644 --- a/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java +++ b/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java @@ -37,6 +37,7 @@ import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.util.TypedValue; @@ -103,7 +104,11 @@ public class RangeSeekBar extends ImageView { private double minDeltaForDefault = 0; private Thumb pressedThumb = null; private boolean notifyWhileDragging = false; + @Nullable private OnRangeSeekBarChangeListener listener; + @Nullable + private TextFormatter textFormatter; + private float downMotionX; @@ -692,9 +697,17 @@ protected synchronized void onDraw(@NonNull Canvas canvas) { } - // TODO maaaaybe make this private and add formatter? + + @SuppressWarnings("unused") + public void setTextFormatter(@NonNull TextFormatter textFormatter) { + this.textFormatter = textFormatter; + } + private String valueToString(int value) { - return String.valueOf(value); + if (textFormatter == null) { + return String.valueOf(value); + } + return textFormatter.formatValue(value); } /** @@ -897,4 +910,33 @@ public interface OnRangeSeekBarChangeListener { void onStopTrackingTouch(RangeSeekBar rangeSeekBar); } + /** + * An utility interface allowing clients to format the text shown by the bar in any way they want. + */ + public interface TextFormatter { + String formatValue(int value); + } + + /** + * A helper abstract class so that clients can implement only the listener methods they care about + * from {@link OnRangeSeekBarChangeListener} + */ + public abstract class SimpleRangeSeekBarChangeListener implements OnRangeSeekBarChangeListener { + + @Override + public void onRangeSeekBarValuesChanged(RangeSeekBar rangeSeekBar, int selectedMinValue, int selectedMaxValue) { + + } + + @Override + public void onStartTrackingTouch(RangeSeekBar rangeSeekBar) { + + } + + @Override + public void onStopTrackingTouch(RangeSeekBar rangeSeekBar) { + + } + } + } From c9645315e6769ffb4da20ff0da0bb174b2371a85 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 25 Nov 2016 16:34:35 +0000 Subject: [PATCH 08/15] Lint cleanup --- rangeseekbar/build.gradle | 1 + rangeseekbar/src/main/res/values/strings.xml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/rangeseekbar/build.gradle b/rangeseekbar/build.gradle index e7d1c83..97dbb44 100644 --- a/rangeseekbar/build.gradle +++ b/rangeseekbar/build.gradle @@ -22,6 +22,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-compat:25.0.1' + compile 'com.android.support:appcompat-v7:25.0.1' // Robolectric testCompile 'org.robolectric:robolectric:3.1.4' diff --git a/rangeseekbar/src/main/res/values/strings.xml b/rangeseekbar/src/main/res/values/strings.xml index 5136f1f..84ad260 100644 --- a/rangeseekbar/src/main/res/values/strings.xml +++ b/rangeseekbar/src/main/res/values/strings.xml @@ -1,6 +1,5 @@ - RangeSeekBar Demo Min Max From ad6fbf84e031958199039cf8ac8bb3cfa14cabdb Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 2 Dec 2016 14:17:24 +0000 Subject: [PATCH 09/15] Add empty test --- .../florescu/android/rangeseekbar/RangeSeekBarTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java b/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java index 0d0583c..a2ea926 100644 --- a/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java +++ b/rangeseekbar/src/test/java/org/florescu/android/rangeseekbar/RangeSeekBarTest.java @@ -1,12 +1,19 @@ package org.florescu.android.rangeseekbar; +import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import static org.assertj.core.api.Assertions.assertThat; + @RunWith(RobolectricTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class RangeSeekBarTest { - + @Test + public void emptyTest() { + // TODO + assertThat(true).isTrue(); + } } \ No newline at end of file From 3d01f52c6d8384506695a52361a1573310fa1686 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 2 Dec 2016 14:25:09 +0000 Subject: [PATCH 10/15] Update travis --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f504eb3..39e55ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: android -jdk: oraclejdk7 +jdk: oraclejdk8 android: components: - platform-tools - tools - - build-tools-23.0.3 - - android-23 + - build-tools-25.0.0 + - android-25 #Additional libs from Android - extra-google-m2repository From 458e941b2918f22117e74f64e06fbc737f9ab981 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 2 Dec 2016 15:14:48 +0000 Subject: [PATCH 11/15] Cleanup --- .../android/rangeseekbar/RangeSeekBar.java | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java b/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java index 8a47573..503e4d8 100644 --- a/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java +++ b/rangeseekbar/src/main/java/org/florescu/android/rangeseekbar/RangeSeekBar.java @@ -50,7 +50,6 @@ /** * Widget that lets users select a minimum and maximum value on a given numerical range. - * The range value types can be any {@link Number}.
// TODO get rid of all number references *
* Improved {@link android.view.MotionEvent} handling for smoother use, anti-aliased painting for improved aesthetics. * @@ -165,7 +164,6 @@ public RangeSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int d init(context, attrs); } - @SuppressWarnings("unchecked") private int extractNumericValueFromAttributes(TypedArray a, int attribute, int defaultValue) { TypedValue tv = a.peekValue(attribute); if (tv == null) { @@ -254,7 +252,7 @@ private void init(Context context, AttributeSet attrs) { thumbHalfWidth = 0.5f * thumbImage.getWidth(); thumbHalfHeight = 0.5f * thumbImage.getHeight(); - setValuePrimAndNumberType(); + setValuePrim(); textSize = PixelUtil.dpToPx(context, DEFAULT_TEXT_SIZE_IN_DP); distanceToTop = PixelUtil.dpToPx(context, DEFAULT_TEXT_DISTANCE_TO_TOP_IN_DP); @@ -287,7 +285,7 @@ private void init(Context context, AttributeSet attrs) { public void setRangeValues(int minValue, int maxValue) { this.absoluteMinValue = minValue; this.absoluteMaxValue = maxValue; - setValuePrimAndNumberType(); + setValuePrim(); } public void setRangeValues(int minValue, int maxValue, int step) { @@ -295,26 +293,20 @@ public void setRangeValues(int minValue, int maxValue, int step) { setRangeValues(minValue, maxValue); } - // TODO should this be just @ColorRes - public void setTextAboveThumbsColor(@ColorInt int textAboveThumbsColor) { - this.textAboveThumbsColor = textAboveThumbsColor; - invalidate(); - } - public void setTextAboveThumbsColorResource(@ColorRes int resId) { - setTextAboveThumbsColor(ContextCompat.getColor(getContext(), resId)); + this.textAboveThumbsColor = ContextCompat.getColor(getContext(), resId); + invalidate(); } - @SuppressWarnings("unchecked") // only used to set default values when initialised from XML without any values specified private void setRangeToDefaultValues() { this.absoluteMinValue = DEFAULT_MINIMUM; this.absoluteMaxValue = DEFAULT_MAXIMUM; this.absoluteStepValue = DEFAULT_STEP; - setValuePrimAndNumberType(); + setValuePrim(); } - private void setValuePrimAndNumberType() { + private void setValuePrim() { absoluteMinValuePrim = absoluteMinValue; absoluteMaxValuePrim = absoluteMaxValue; absoluteStepValuePrim = absoluteStepValue; @@ -384,7 +376,7 @@ public boolean isDragging() { /** * Sets the currently selected minimum value. The widget will be invalidated and redrawn. * - * @param value The Number value to set the minimum value to. Will be clamped to given absolute minimum/maximum range. + * @param value The value to set the minimum value to. Will be clamped to given absolute minimum/maximum range. */ public void setSelectedMinValue(int value) { // in case absoluteMinValue == absoluteMaxValue, avoid division by zero when normalizing. @@ -407,7 +399,7 @@ public int getSelectedMaxValue() { /** * Sets the currently selected maximum value. The widget will be invalidated and redrawn. * - * @param value The Number value to set the maximum value to. Will be clamped to given absolute minimum/maximum range. + * @param value The value to set the maximum value to. Will be clamped to given absolute minimum/maximum range. */ public void setSelectedMaxValue(int value) { // in case absoluteMinValue == absoluteMaxValue, avoid division by zero when normalizing. @@ -535,7 +527,6 @@ private void onSecondaryPointerUp(MotionEvent ev) { if (pointerId == activePointerId) { // This was our active pointer going up. Choose // a new active pointer and adjust accordingly. - // TODO: Make this decision more intelligent. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; downMotionX = ev.getX(newPointerIndex); activePointerId = ev.getPointerId(newPointerIndex); @@ -714,7 +705,6 @@ private String valueToString(int value) { * Overridden to save instance state when device orientation changes. This method is called automatically if you assign an id to the RangeSeekBar widget using the {@link #setId(int)} method. Other members of this class than the normalized min and max values don't need to be saved. */ @Override - // TODO test these protected Parcelable onSaveInstanceState() { final Bundle bundle = new Bundle(); bundle.putParcelable("SUPER", super.onSaveInstanceState()); @@ -820,19 +810,18 @@ private void setNormalizedMaxValue(double value) { } /** - * Converts a normalized value to a Number object in the value space between absolute minimum and maximum. + * Converts a normalized value to an int in the value space between absolute minimum and maximum. */ @SuppressWarnings("unchecked") private int normalizedToValue(double normalized) { double v = absoluteMinValuePrim + normalized * (absoluteMaxValuePrim - absoluteMinValuePrim); - // TODO parameterize this rounding to allow variable decimal points return (int) (Math.round(v * 100) / 100d); } /** - * Converts the given Number value to a normalized double. + * Converts the given value to a normalized double. * - * @param value The Number value to normalize. + * @param value The int value to normalize. * @return The normalized double. */ private double valueToNormalized(int value) { From ff5cd68ca637195685d016ad179db974458c287f Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 2 Dec 2016 15:14:57 +0000 Subject: [PATCH 12/15] Add ids for restoring state --- rangeseekbar-sample/src/main/res/layout/main.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rangeseekbar-sample/src/main/res/layout/main.xml b/rangeseekbar-sample/src/main/res/layout/main.xml index a2c1774..fbbba06 100644 --- a/rangeseekbar-sample/src/main/res/layout/main.xml +++ b/rangeseekbar-sample/src/main/res/layout/main.xml @@ -28,6 +28,7 @@ android:text="Range seek bar from xml with default range"/> @@ -38,6 +39,7 @@ Date: Fri, 2 Dec 2016 15:28:06 +0000 Subject: [PATCH 13/15] Theme sample --- rangeseekbar-sample/src/main/AndroidManifest.xml | 3 ++- rangeseekbar-sample/src/main/res/layout/main.xml | 2 +- rangeseekbar-sample/src/main/res/values/styles.xml | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/rangeseekbar-sample/src/main/AndroidManifest.xml b/rangeseekbar-sample/src/main/AndroidManifest.xml index e9995a9..1b44aca 100644 --- a/rangeseekbar-sample/src/main/AndroidManifest.xml +++ b/rangeseekbar-sample/src/main/AndroidManifest.xml @@ -9,7 +9,8 @@ android:label="@string/app_name"> + android:label="@string/app_name" + android:theme="@style/AppTheme"> diff --git a/rangeseekbar-sample/src/main/res/layout/main.xml b/rangeseekbar-sample/src/main/res/layout/main.xml index fbbba06..ef5383d 100644 --- a/rangeseekbar-sample/src/main/res/layout/main.xml +++ b/rangeseekbar-sample/src/main/res/layout/main.xml @@ -8,7 +8,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:background="#263238" + android:padding="8dp"> - - From d9e03519b734d57717d627387e17634ece969284 Mon Sep 17 00:00:00 2001 From: Alex Florescu Date: Fri, 2 Dec 2016 15:31:43 +0000 Subject: [PATCH 14/15] Update example --- .../rangeseekbar/sample/DemoActivity.java | 10 ++++++++ .../src/main/res/layout/main.xml | 23 +++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java b/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java index 889c794..1794903 100644 --- a/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java +++ b/rangeseekbar-sample/src/main/java/org/florescu/android/rangeseekbar/sample/DemoActivity.java @@ -53,5 +53,15 @@ public String formatValue(int value) { // Seek bar for which we will set text color in code RangeSeekBar rangeSeekBarTextColorWithCode = (RangeSeekBar) findViewById(R.id.rangeSeekBarTextColorWithCode); rangeSeekBarTextColorWithCode.setTextAboveThumbsColorResource(android.R.color.holo_blue_bright); + + // Seekbar with double values + RangeSeekBar rsbDoubles = (RangeSeekBar) findViewById(R.id.rsb_double_values); + rsbDoubles.setRangeValues(1523, 14835); + rsbDoubles.setTextFormatter(new RangeSeekBar.TextFormatter() { + @Override + public String formatValue(int value) { + return "£" + value / 100d; + } + }); } } diff --git a/rangeseekbar-sample/src/main/res/layout/main.xml b/rangeseekbar-sample/src/main/res/layout/main.xml index ef5383d..0e9f5d2 100644 --- a/rangeseekbar-sample/src/main/res/layout/main.xml +++ b/rangeseekbar-sample/src/main/res/layout/main.xml @@ -59,18 +59,17 @@ rsb:absoluteMinValue="20" rsb:step="10" /> - - - - - - - - - - - - + + + + + Date: Fri, 2 Dec 2016 15:39:09 +0000 Subject: [PATCH 15/15] Update README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04a3cf9..64315f2 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,11 @@ The rangeseekbar-sample shows the available features and customizations in code ``` * For the latest work-in-progress snapshot: +(NOTE: Version 1.0 is making breaking API modifications and the API may continue to change until development has finished) ```groovy dependencies { - compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:1.4.0-SNAPSHOT' + compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:1.0.0-SNAPSHOT' } ```