From 585a6dee1d33faee9f0ef723338af4cc7d4be583 Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Tue, 11 May 2021 09:23:44 +0200 Subject: [PATCH 1/8] added option to different text and toggle color added uppercase/lowercase option --- Readme.md | 11 ++- .../res/layout/activity_labeled_switch.xml | 57 ++++++++++++ screenshots/version 1/LabeledSwitch.png | Bin 23340 -> 30901 bytes .../angads25/toggle/widget/LabeledSwitch.java | 83 +++++++++++++++--- toggle/src/main/res/values/attrs.xml | 16 ++++ 5 files changed, 155 insertions(+), 12 deletions(-) mode change 100755 => 100644 screenshots/version 1/LabeledSwitch.png diff --git a/Readme.md b/Readme.md index 4d2f99a..e127e69 100755 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,15 @@ # Toggle Android Library for Custom Switches. +### Added feature + 1. Added different toggle and text color + app:colorText="#ffffff" + app:colorToggle="#ffffff" + + 2. Added text modification option + app:textUpperCase + app:textLowerCase + ### Developed by [Angad Singh](https://www.github.com/angads25) ([@angads25](https://www.twitter.com/angads25)) @@ -51,7 +60,7 @@ Android Library for Custom Switches. * Labeled Switch | Designed by - [Shweta Gupta](https://dribbble.com/shwetagupta) -![Labeled Switch](https://raw.githubusercontent.com/Angads25/android-toggle/release/screenshots/version%201/LabeledSwitch.png) +![Labeled Switch](https://raw.githubusercontent.com/jozsefmezei/android-toggle/release/screenshots/version%201/LabeledSwitch.png) * Day Night Switch | Designed by - [Ramakrishna V](https://dribbble.com/RamakrishnaUX) diff --git a/app/src/main/res/layout/activity_labeled_switch.xml b/app/src/main/res/layout/activity_labeled_switch.xml index 4e71755..2ec14bc 100755 --- a/app/src/main/res/layout/activity_labeled_switch.xml +++ b/app/src/main/res/layout/activity_labeled_switch.xml @@ -147,4 +147,61 @@ app:textOff="STOP" app:colorBorder="@color/colorAccent" /> + + + + + + + + + \ No newline at end of file diff --git a/screenshots/version 1/LabeledSwitch.png b/screenshots/version 1/LabeledSwitch.png old mode 100755 new mode 100644 index f3ad341ecf3f020f2a522121d53c25cf6b2a8072..4f554bbb7496f4b215e58107f0ed0a18635c95f7 GIT binary patch literal 30901 zcmdSBRa9JG@HH6RAviSd4#C}>;O->2yK5Sk0KwfMSb*S8K z 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
LJ3Bi@PKw4nW7yp!&*h;pDbDl^z=X{W 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 diff --git a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java index bc7daa9..8dd374d 100755 --- a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java +++ b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java @@ -45,7 +45,8 @@ public class LabeledSwitch extends ToggleableView { private int colorBorder; private int colorDisabled; - private int textSize; + private int toggleColor = Integer.MIN_VALUE; + private int textColor = Integer.MIN_VALUE; private int outerRadii; private int thumbRadii; @@ -57,6 +58,11 @@ public class LabeledSwitch extends ToggleableView { private String labelOn; private String labelOff; + private boolean textUpperCase; + private boolean textLowerCase; + + private int textSize; + private RectF thumbBounds; private RectF leftBgArc; @@ -155,6 +161,10 @@ private void initProperties(AttributeSet attrs) { accentColor = getResources().getColor(R.color.colorAccent); } colorBorder = tarr.getColor(R.styleable.Toggle_colorBorder, accentColor); + } else if (attr == R.styleable.Toggle_colorText) { + textColor = tarr.getColor(R.styleable.Toggle_colorText, Integer.MIN_VALUE); + } else if (attr == R.styleable.Toggle_colorToggle) { + toggleColor = tarr.getColor(R.styleable.Toggle_colorToggle, Integer.MIN_VALUE); } else if (attr == R.styleable.Toggle_colorOn) { int accentColor; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { @@ -174,6 +184,10 @@ private void initProperties(AttributeSet attrs) { textSize = tarr.getDimensionPixelSize(R.styleable.Toggle_android_textSize, defaultTextSize); } else if(attr == R.styleable.Toggle_android_enabled) { enabled = tarr.getBoolean(R.styleable.Toggle_android_enabled, false); + } else if(attr == R.styleable.Toggle_textLowerCase) { + textLowerCase = tarr.getBoolean(R.styleable.Toggle_textLowerCase, false); + } else if(attr == R.styleable.Toggle_textUpperCase) { + textUpperCase = tarr.getBoolean(R.styleable.Toggle_textUpperCase, false); } } } @@ -234,54 +248,65 @@ private void initProperties(AttributeSet attrs) { paint.setColor(onColor); float centerX = (width - padding - ((padding + (padding >>> 1)) + (thumbRadii << 1))) >>> 1; - canvas.drawText(labelOff, (padding + (padding >>> 1)) + (thumbRadii << 1) + centerX - (paint.measureText(labelOff) / 2), (height >>> 1) + textCenter, paint); + String text = textUpperCase ? labelOff.toUpperCase() : textLowerCase ? labelOff.toLowerCase() : labelOff; + canvas.drawText(text, (padding + (padding >>> 1)) + (thumbRadii << 1) + centerX - (paint.measureText(labelOff) / 2), (height >>> 1) + textCenter, paint); alpha = (int)(((thumbBounds.centerX() - (width >>> 1)) / (thumbOnCenterX - (width >>> 1))) * 255); alpha = (alpha < 0 ? 0 : (alpha > 255 ? 255 : alpha)); - int offColor = Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)); + int offColor = textColor > Integer.MIN_VALUE ? Color.argb(alpha, Color.red(textColor), Color.green(textColor), Color.blue(textColor)) : + Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)); paint.setColor(offColor); int maxSize = width - (padding << 1) - (thumbRadii << 1); centerX = (((padding >>> 1) + maxSize) - padding) >>> 1; - canvas.drawText(labelOn, padding + centerX - (paint.measureText(labelOn) / 2), (height >>> 1) + textCenter, paint); + text = textUpperCase ? labelOn.toUpperCase() : textLowerCase ? labelOn.toLowerCase() : labelOn; + canvas.drawText(text, padding + centerX - (paint.measureText(labelOn) / 2), (height >>> 1) + textCenter, paint); } else { int alpha = (int)(((thumbBounds.centerX() - (width >>> 1)) / (thumbOnCenterX - (width >>> 1))) * 255); alpha = (alpha < 0 ? 0 : (alpha > 255 ? 255 : alpha)); - int offColor = Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)); + int offColor = textColor > Integer.MIN_VALUE ? Color.argb(alpha, Color.red(textColor), Color.green(textColor), Color.blue(textColor)) : + Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)); paint.setColor(offColor); int maxSize = width - (padding << 1) - (thumbRadii << 1); float centerX = (((padding >>> 1) + maxSize) - padding) >>> 1; - canvas.drawText(labelOn, padding + centerX - (paint.measureText(labelOn) / 2), (height >>> 1) + textCenter, paint); + String text = textUpperCase ? labelOn.toUpperCase() : textLowerCase ? labelOn.toLowerCase() : labelOn; + canvas.drawText(text, padding + centerX - (paint.measureText(labelOn) / 2), (height >>> 1) + textCenter, paint); alpha = (int)((((width >>> 1) - thumbBounds.centerX()) / ((width >>> 1) - thumbOffCenterX)) * 255); alpha = (alpha < 0 ? 0 : (alpha > 255 ? 255 : alpha)); int onColor; if(isEnabled()) { - onColor = Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)); + onColor = textColor > Integer.MIN_VALUE ? Color.argb(alpha, Color.red(textColor), Color.green(textColor), Color.blue(textColor)) : + Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)); + } else { onColor = Color.argb(alpha, Color.red(colorDisabled), Color.green(colorDisabled), Color.blue(colorDisabled)); } paint.setColor(onColor); centerX = (width - padding - ((padding + (padding >>> 1)) + (thumbRadii << 1))) >>> 1; - canvas.drawText(labelOff, (padding + (padding >>> 1)) + (thumbRadii << 1) + centerX - (paint.measureText(labelOff) / 2), (height >>> 1) + textCenter, paint); + text = textUpperCase ? labelOff.toUpperCase() : textLowerCase ? labelOff.toLowerCase() : labelOff; + canvas.drawText(text, (padding + (padding >>> 1)) + (thumbRadii << 1) + centerX - (paint.measureText(labelOff) / 2), (height >>> 1) + textCenter, paint); } // Drawing Switch Thumb here { int alpha = (int) (((thumbBounds.centerX() - thumbOffCenterX) / (thumbOnCenterX - thumbOffCenterX)) * 255); alpha = (alpha < 0 ? 0 : (alpha > 255 ? 255 : alpha)); - int offColor = Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)); - paint.setColor(offColor); + int thumbColor = toggleColor > Integer.MIN_VALUE ? Color.argb(alpha, Color.red(toggleColor), Color.green(toggleColor), Color.blue(toggleColor)) : + Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)); + paint.setColor(thumbColor); canvas.drawCircle(thumbBounds.centerX(), thumbBounds.centerY(), thumbRadii, paint); alpha = (int) (((thumbOnCenterX - thumbBounds.centerX()) / (thumbOnCenterX - thumbOffCenterX)) * 255); alpha = (alpha < 0 ? 0 : (alpha > 255 ? 255 : alpha)); int onColor; if(isEnabled()) { - onColor = Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)); + onColor = textColor > Integer.MIN_VALUE ? Color.argb(alpha, Color.red(textColor), Color.green(textColor), Color.blue(textColor)) : + Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)); + } else { onColor = Color.argb(alpha, Color.red(colorDisabled), Color.green(colorDisabled), Color.blue(colorDisabled)); } @@ -615,4 +640,40 @@ public void setTextSize(int textSize) { this.textSize = (int)(textSize * getResources().getDisplayMetrics().scaledDensity); invalidate(); } + + /** + *

Changes the toggle color.

+ * + * @param toggleColor the color. + */ + public void setToggleColor(int toggleColor) { + this.toggleColor = toggleColor; + } + + /** + *

Changes the label color.

+ * + * @param textColor the color. + */ + public void setTextColor(int textColor) { + this.textColor = textColor; + } + + /** + *

Changes the label case to upper.

+ * + * @param textUpperCase whether text upper case. + */ + public void setTextUpperCase(boolean textUpperCase) { + this.textUpperCase = textUpperCase; + } + + /** + *

Changes the label case to lower.

+ * + * @param textLowerCase whether text lower case. + */ + public void setTextLowerCase(boolean textLowerCase) { + this.textLowerCase = textLowerCase; + } } diff --git a/toggle/src/main/res/values/attrs.xml b/toggle/src/main/res/values/attrs.xml index 82612f6..74b2f4a 100755 --- a/toggle/src/main/res/values/attrs.xml +++ b/toggle/src/main/res/values/attrs.xml @@ -19,6 +19,22 @@ name="colorOn" format="color"/> + + + + + + + + From 0f2f2ed9338a2c085053d3e72bd093da434cb9ea Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Tue, 11 May 2021 09:26:44 +0200 Subject: [PATCH 2/8] updated version --- toggle/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toggle/build.gradle b/toggle/build.gradle index 08f3f6c..9734bef 100755 --- a/toggle/build.gradle +++ b/toggle/build.gradle @@ -13,7 +13,7 @@ ext { siteUrl = 'https://github.com/angads25/android-toggle' gitUrl = 'https://github.com/angads25/android-toggle.git' - libraryVersion = '1.1.0' + libraryVersion = '1.1.1' developerId = 'angads25' developerName = 'Angad Singh' @@ -31,7 +31,7 @@ android { minSdkVersion 14 targetSdkVersion 28 versionCode 1 - versionName "1.1.0" + versionName "1.1.1" } buildTypes { release { From 9bdd893ebd85574cecf1f4d14d01fb6af4f20020 Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Tue, 11 May 2021 09:43:45 +0200 Subject: [PATCH 3/8] updated readme file --- Readme.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index e127e69..7332086 100755 --- a/Readme.md +++ b/Readme.md @@ -17,15 +17,25 @@ Android Library for Custom Switches. [![API](https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=14) [![Build Status](https://travis-ci.org/Angads25/android-toggle.svg?branch=release)](https://travis-ci.org/Angads25/android-toggle) ### Mentions: -[![Download](https://api.bintray.com/packages/angads25/maven/Toggle/images/download.svg)](https://bintray.com/angads25/maven/Toggle/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.angads25/toggle/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.angads25/toggle) +[![](https://jitpack.io/v/jozsefmezei/android-toggle.svg)](https://jitpack.io/#jozsefmezei/android-toggle) ### Read all about internal classes and functions in the [wiki](https://github.com/Angads25/android-toggle/wiki). ### Installation -* Library is also Available in MavenCentral, So just put this in your app dependencies to use it: +Add it in your root build.gradle at the end of repositories: ```gradle - implementation 'com.github.angads25:toggle:1.1.0' + allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } + } +``` + +* Put this in your app dependencies: +```gradle + implementation 'com.github.jozsefmezei:android-toggle:1.1.1' ``` ### Usage From eec92aad9097a6efb1090dfee631ec953b6e9416 Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Tue, 11 May 2021 09:45:04 +0200 Subject: [PATCH 4/8] updated readme file --- Readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 7332086..9cba537 100755 --- a/Readme.md +++ b/Readme.md @@ -3,12 +3,12 @@ Android Library for Custom Switches. ### Added feature 1. Added different toggle and text color - app:colorText="#ffffff" - app:colorToggle="#ffffff" + - app:colorText="#ffffff" + - app:colorToggle="#ffffff" 2. Added text modification option - app:textUpperCase - app:textLowerCase + - app:textUpperCase + - app:textLowerCase ### Developed by [Angad Singh](https://www.github.com/angads25) ([@angads25](https://www.twitter.com/angads25)) From fe6d60b89edb1db94e3406a07394d3dfeef7d6da Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Tue, 11 May 2021 10:38:36 +0200 Subject: [PATCH 5/8] added start animation from position --- Readme.md | 3 +++ .../main/res/layout/activity_labeled_switch.xml | 17 +++++++++++++++++ toggle/build.gradle | 4 ++-- .../angads25/toggle/widget/LabeledSwitch.java | 16 ++++++++++++++-- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 9cba537..f022529 100755 --- a/Readme.md +++ b/Readme.md @@ -10,6 +10,9 @@ Android Library for Custom Switches. - app:textUpperCase - app:textLowerCase + 3. Start toggle animation from touched X position or from the toggle position + - setStartAnimationFromTouchPosition (only from code) + ### Developed by [Angad Singh](https://www.github.com/angads25) ([@angads25](https://www.twitter.com/angads25)) diff --git a/app/src/main/res/layout/activity_labeled_switch.xml b/app/src/main/res/layout/activity_labeled_switch.xml index 2ec14bc..25427e3 100755 --- a/app/src/main/res/layout/activity_labeled_switch.xml +++ b/app/src/main/res/layout/activity_labeled_switch.xml @@ -204,4 +204,21 @@ app:colorOn="@color/colorPrimary" app:colorOff="#00c4a6"/> + + + \ No newline at end of file diff --git a/toggle/build.gradle b/toggle/build.gradle index 9734bef..a5f26ed 100755 --- a/toggle/build.gradle +++ b/toggle/build.gradle @@ -13,7 +13,7 @@ ext { siteUrl = 'https://github.com/angads25/android-toggle' gitUrl = 'https://github.com/angads25/android-toggle.git' - libraryVersion = '1.1.1' + libraryVersion = '1.1.2' developerId = 'angads25' developerName = 'Angad Singh' @@ -31,7 +31,7 @@ android { minSdkVersion 14 targetSdkVersion 28 versionCode 1 - versionName "1.1.1" + versionName "1.1.2" } buildTypes { release { diff --git a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java index 8dd374d..f84d016 100755 --- a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java +++ b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java @@ -76,6 +76,8 @@ public class LabeledSwitch extends ToggleableView { private float thumbOnCenterX; private float thumbOffCenterX; + protected boolean startAnimationFromTouchPosition = true; + /** * Simple constructor to use when creating a switch from code. * @param context The Context the switch is running in, through which it can @@ -244,7 +246,8 @@ private void initProperties(AttributeSet attrs) { if(isOn) { int alpha = (int)((((width >>> 1) - thumbBounds.centerX()) / ((width >>> 1) - thumbOffCenterX)) * 255); alpha = (alpha < 0 ? 0 : (alpha > 255 ? 255 : alpha)); - int onColor = Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)); + int onColor = textColor > Integer.MIN_VALUE ? Color.argb(alpha, Color.red(textColor), Color.green(textColor), Color.blue(textColor)) : + Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)); paint.setColor(onColor); float centerX = (width - padding - ((padding + (padding >>> 1)) + (thumbRadii << 1))) >>> 1; @@ -411,7 +414,7 @@ private void initProperties(AttributeSet attrs) { */ @Override public final boolean onTouchEvent(MotionEvent event) { if(isEnabled()) { - float x = event.getX(); + float x = startAnimationFromTouchPosition ? event.getX() : thumbBounds.centerX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { startTime = System.currentTimeMillis(); @@ -676,4 +679,13 @@ public void setTextUpperCase(boolean textUpperCase) { public void setTextLowerCase(boolean textLowerCase) { this.textLowerCase = textLowerCase; } + + /** + *

Start switch animation from start or from touch position. Default value is true.

+ * + * @param startAnimationFromTouchPosition Start from touch position if it is true. + */ + public void setStartAnimationFromTouchPosition(boolean startAnimationFromTouchPosition) { + this.startAnimationFromTouchPosition = startAnimationFromTouchPosition; + } } From e5dddbd7aebceb399aefb07894b0b8d021d5dd1d Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Tue, 18 May 2021 09:29:41 +0200 Subject: [PATCH 6/8] outsourced interpolator and duration added option to skip clicks and touches during animation --- Readme.md | 8 ++ .../toggledemo/LabeledSwitchActivity.java | 7 + toggle/build.gradle | 6 +- .../angads25/toggle/widget/LabeledSwitch.java | 121 ++++++++++++++++-- 4 files changed, 131 insertions(+), 11 deletions(-) diff --git a/Readme.md b/Readme.md index f022529..34d04b0 100755 --- a/Readme.md +++ b/Readme.md @@ -13,6 +13,14 @@ Android Library for Custom Switches. 3. Start toggle animation from touched X position or from the toggle position - setStartAnimationFromTouchPosition (only from code) + 4. Outsourced properties + - setDuration (only from code) + - setInterpolator (only from code) + + 5. Added option the disable touch during animation + - setInterruptAnimation (only from code) + + ### Developed by [Angad Singh](https://www.github.com/angads25) ([@angads25](https://www.twitter.com/angads25)) diff --git a/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java b/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java index ce911c3..b45708e 100755 --- a/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java +++ b/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java @@ -21,6 +21,7 @@ import android.os.Handler; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.app.AppCompatActivity; +import android.view.animation.BounceInterpolator; import com.github.angads25.toggle.widget.LabeledSwitch; @@ -36,6 +37,8 @@ public class LabeledSwitchActivity extends AppCompatActivity { R.id.switch1, R.id.switch2, R.id.switch4, R.id.switch5, R.id.switch7, R.id.switch8, + R.id.switch9, R.id.switch10, R.id.switch12, + R.id.switch12, R.id.switch13 }; private LabeledSwitch[] labeledSwitches; @@ -76,6 +79,10 @@ public void run() { labeledSwitches[2].setTypeface(openSansBold); labeledSwitches[3].setTypeface(openSansBold); + labeledSwitches[10].setDuration(5111); + labeledSwitches[10].setInterpolator(new BounceInterpolator()); + labeledSwitches[10].setStartAnimationFromTouchPosition(false); + labeledSwitches[10].setInterruptAnimation(false); } @Override diff --git a/toggle/build.gradle b/toggle/build.gradle index a5f26ed..31f90b2 100755 --- a/toggle/build.gradle +++ b/toggle/build.gradle @@ -13,7 +13,7 @@ ext { siteUrl = 'https://github.com/angads25/android-toggle' gitUrl = 'https://github.com/angads25/android-toggle.git' - libraryVersion = '1.1.2' + libraryVersion = '1.1.3' developerId = 'angads25' developerName = 'Angad Singh' @@ -30,8 +30,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 28 - versionCode 1 - versionName "1.1.2" + versionCode 2 + versionName "1.1.3" } buildTypes { release { diff --git a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java index f84d016..5bc5ce7 100755 --- a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java +++ b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java @@ -16,6 +16,7 @@ package com.github.angads25.toggle.widget; +import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; @@ -27,6 +28,7 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.Interpolator; import com.github.angads25.toggle.R; import com.github.angads25.toggle.model.ToggleableView; @@ -54,6 +56,8 @@ public class LabeledSwitch extends ToggleableView { private Paint paint; private long startTime; + private long duration; + private Interpolator interpolator = new AccelerateDecelerateInterpolator(); private String labelOn; private String labelOff; @@ -77,6 +81,8 @@ public class LabeledSwitch extends ToggleableView { private float thumbOffCenterX; protected boolean startAnimationFromTouchPosition = true; + protected boolean interruptAnimation = true; + protected boolean allowClick = true; /** * Simple constructor to use when creating a switch from code. @@ -378,6 +384,7 @@ private void initProperties(AttributeSet attrs) { */ @Override public final boolean performClick() { super.performClick(); + if(!allowClick) return false; if (isOn) { ValueAnimator switchColor = ValueAnimator.ofFloat(width - padding - thumbRadii, padding); switchColor.addUpdateListener(animation -> { @@ -385,8 +392,25 @@ private void initProperties(AttributeSet attrs) { thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); - switchColor.setInterpolator(new AccelerateDecelerateInterpolator()); - switchColor.setDuration(250); + switchColor.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + if(!interruptAnimation) allowClick = false; + } + + @Override + public void onAnimationEnd(Animator animation) { + allowClick = true; + } + + @Override + public void onAnimationCancel(Animator animation) {} + + @Override + public void onAnimationRepeat(Animator animation) {} + }); + switchColor.setInterpolator(interpolator); + switchColor.setDuration(duration); switchColor.start(); } else { ValueAnimator switchColor = ValueAnimator.ofFloat(padding, width - padding - thumbRadii); @@ -395,8 +419,25 @@ private void initProperties(AttributeSet attrs) { thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); - switchColor.setInterpolator(new AccelerateDecelerateInterpolator()); - switchColor.setDuration(250); + switchColor.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + if(!interruptAnimation) allowClick = false; + } + + @Override + public void onAnimationEnd(Animator animation) { + allowClick = true; + } + + @Override + public void onAnimationCancel(Animator animation) {} + + @Override + public void onAnimationRepeat(Animator animation) {} + }); + switchColor.setInterpolator(interpolator); + switchColor.setDuration(duration); switchColor.start(); } isOn =! isOn; @@ -413,6 +454,7 @@ private void initProperties(AttributeSet attrs) { * @return True if the event was handled, false otherwise. */ @Override public final boolean onTouchEvent(MotionEvent event) { + if(!allowClick) return false; if(isEnabled()) { float x = startAnimationFromTouchPosition ? event.getX() : thumbBounds.centerX(); switch (event.getAction()) { @@ -443,8 +485,25 @@ private void initProperties(AttributeSet attrs) { thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); - switchColor.setInterpolator(new AccelerateDecelerateInterpolator()); - switchColor.setDuration(250); + switchColor.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + if(!interruptAnimation) allowClick = false; + } + + @Override + public void onAnimationEnd(Animator animation) { + allowClick = true; + } + + @Override + public void onAnimationCancel(Animator animation) {} + + @Override + public void onAnimationRepeat(Animator animation) {} + }); + switchColor.setInterpolator(interpolator); + switchColor.setDuration(duration); switchColor.start(); isOn = true; } else { @@ -454,8 +513,25 @@ private void initProperties(AttributeSet attrs) { thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); - switchColor.setInterpolator(new AccelerateDecelerateInterpolator()); - switchColor.setDuration(250); + switchColor.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + if(!interruptAnimation) setEnabled(false); + } + + @Override + public void onAnimationEnd(Animator animation) { + setEnabled(true); + } + + @Override + public void onAnimationCancel(Animator animation) { } + + @Override + public void onAnimationRepeat(Animator animation) { } + }); + switchColor.setInterpolator(interpolator); + switchColor.setDuration(duration); switchColor.start(); isOn = false; } @@ -688,4 +764,33 @@ public void setTextLowerCase(boolean textLowerCase) { public void setStartAnimationFromTouchPosition(boolean startAnimationFromTouchPosition) { this.startAnimationFromTouchPosition = startAnimationFromTouchPosition; } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public Interpolator getInterpolator() { + return interpolator; + } + + public void setInterpolator(Interpolator interpolator) { + this.interpolator = interpolator; + } + + public boolean isInterruptAnimation() { + return interruptAnimation; + } + + /** + *

Added option to skip clicks and touches during animation.

+ * + * @param interruptAnimation False means that clicks are not allowed during animation. + */ + public void setInterruptAnimation(boolean interruptAnimation) { + this.interruptAnimation = interruptAnimation; + } } From 26a4be2f2c78ea7074b1a2270e98c557b0bb991f Mon Sep 17 00:00:00 2001 From: Jozsef Mezei Date: Wed, 19 May 2021 15:22:25 +0200 Subject: [PATCH 7/8] added animation listener to follow the toggle position in percents --- .../toggledemo/LabeledSwitchActivity.java | 9 ++++++++ toggle/build.gradle | 6 ++--- .../toggle/interfaces/OnAnimateListener.java | 8 +++++++ .../angads25/toggle/model/ToggleableView.java | 18 +++++++++++++++ .../angads25/toggle/widget/LabeledSwitch.java | 22 +++++++++++++++++-- 5 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 toggle/src/main/java/com/github/angads25/toggle/interfaces/OnAnimateListener.java diff --git a/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java b/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java index b45708e..746103c 100755 --- a/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java +++ b/app/src/main/java/com/github/angads25/toggledemo/LabeledSwitchActivity.java @@ -21,8 +21,11 @@ import android.os.Handler; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.app.AppCompatActivity; +import android.util.Log; import android.view.animation.BounceInterpolator; +import com.github.angads25.toggle.interfaces.OnAnimateListener; +import com.github.angads25.toggle.model.ToggleableView; import com.github.angads25.toggle.widget.LabeledSwitch; import java.util.Random; @@ -83,6 +86,12 @@ public void run() { labeledSwitches[10].setInterpolator(new BounceInterpolator()); labeledSwitches[10].setStartAnimationFromTouchPosition(false); labeledSwitches[10].setInterruptAnimation(false); + labeledSwitches[10].setOnAnimateListener(new OnAnimateListener() { + @Override + public void onAnimate(ToggleableView toggleableView, float position) { + Log.d("Actual_position_percent", String.valueOf(position)); + } + }); } @Override diff --git a/toggle/build.gradle b/toggle/build.gradle index 31f90b2..c394054 100755 --- a/toggle/build.gradle +++ b/toggle/build.gradle @@ -13,7 +13,7 @@ ext { siteUrl = 'https://github.com/angads25/android-toggle' gitUrl = 'https://github.com/angads25/android-toggle.git' - libraryVersion = '1.1.3' + libraryVersion = '1.1.4' developerId = 'angads25' developerName = 'Angad Singh' @@ -30,8 +30,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 28 - versionCode 2 - versionName "1.1.3" + versionCode 3 + versionName "1.1.4" } buildTypes { release { diff --git a/toggle/src/main/java/com/github/angads25/toggle/interfaces/OnAnimateListener.java b/toggle/src/main/java/com/github/angads25/toggle/interfaces/OnAnimateListener.java new file mode 100644 index 0000000..719f5b4 --- /dev/null +++ b/toggle/src/main/java/com/github/angads25/toggle/interfaces/OnAnimateListener.java @@ -0,0 +1,8 @@ +package com.github.angads25.toggle.interfaces; + +import com.github.angads25.toggle.model.ToggleableView; + +public interface OnAnimateListener { + + void onAnimate(ToggleableView toggleableView, float position); +} diff --git a/toggle/src/main/java/com/github/angads25/toggle/model/ToggleableView.java b/toggle/src/main/java/com/github/angads25/toggle/model/ToggleableView.java index 6b7047b..93a4681 100755 --- a/toggle/src/main/java/com/github/angads25/toggle/model/ToggleableView.java +++ b/toggle/src/main/java/com/github/angads25/toggle/model/ToggleableView.java @@ -21,6 +21,7 @@ import android.view.View; import android.view.ViewDebug; +import com.github.angads25.toggle.interfaces.OnAnimateListener; import com.github.angads25.toggle.interfaces.OnStateChangedListener; import com.github.angads25.toggle.interfaces.OnToggledListener; @@ -57,6 +58,13 @@ public class ToggleableView extends View { */ protected OnToggledListener onToggledListener; + /** + * Listener to inform user about toggle position. Position are based on percentage between 0 and 1. + * + * @see #setOnAnimateListener(OnToggledListener) + */ + protected OnAnimateListener onAnimateListener; + /** * Simple constructor to use when creating a switch from code. * @param context The Context the switch is running in, through which it can @@ -142,4 +150,14 @@ public void setOn(boolean on) { public void setOnToggledListener(OnToggledListener onToggledListener) { this.onToggledListener = onToggledListener; } + + /** + * Register a callback to be invoked when the toggle animate between start and end position. If this switch is not + * enabled, there won't be any event. + * + * @param onAnimateListener The callback that will run + */ + public void setOnAnimateListener(OnAnimateListener onAnimateListener) { + this.onAnimateListener = onAnimateListener; + } } diff --git a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java index 5bc5ce7..67f9aae 100755 --- a/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java +++ b/toggle/src/main/java/com/github/angads25/toggle/widget/LabeledSwitch.java @@ -26,6 +26,7 @@ import android.graphics.RectF; import android.graphics.Typeface; import android.util.AttributeSet; +import android.util.Log; import android.view.MotionEvent; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; @@ -386,9 +387,16 @@ private void initProperties(AttributeSet attrs) { super.performClick(); if(!allowClick) return false; if (isOn) { - ValueAnimator switchColor = ValueAnimator.ofFloat(width - padding - thumbRadii, padding); + float from = width - padding - thumbRadii; + ValueAnimator switchColor = ValueAnimator.ofFloat(from, padding); switchColor.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); + if (onAnimateListener != null){ + float position = (value - padding) / from; + if (position > 1) position = 1; + if (position < 0) position = 0; + onAnimateListener.onAnimate(this, position); + } thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); @@ -413,9 +421,17 @@ public void onAnimationRepeat(Animator animation) {} switchColor.setDuration(duration); switchColor.start(); } else { - ValueAnimator switchColor = ValueAnimator.ofFloat(padding, width - padding - thumbRadii); + float to = width - padding - thumbRadii; + ValueAnimator switchColor = ValueAnimator.ofFloat(padding, to); switchColor.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); + if(onAnimateListener != null){ + float position = (value - padding) / to; + if (position > 1) position = 1; + if (position < 0) position = 0; + + onAnimateListener.onAnimate(this, position); + } thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); @@ -482,6 +498,7 @@ public void onAnimationRepeat(Animator animation) {} ValueAnimator switchColor = ValueAnimator.ofFloat((x > (width - padding - thumbRadii) ? (width - padding - thumbRadii) : x), width - padding - thumbRadii); switchColor.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); + Log.d("Valuef", String.valueOf(value)); thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); @@ -510,6 +527,7 @@ public void onAnimationRepeat(Animator animation) {} ValueAnimator switchColor = ValueAnimator.ofFloat((x < padding ? padding : x), padding); switchColor.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); + Log.d("Valuel", String.valueOf(value)); thumbBounds.set(value, thumbBounds.top, value + thumbRadii, thumbBounds.bottom); invalidate(); }); From 4a9bf1adb63ed0c0a720bcc8d649440a9ec2a1d4 Mon Sep 17 00:00:00 2001 From: jozsefmezei Date: Wed, 19 May 2021 15:25:23 +0200 Subject: [PATCH 8/8] Updated readme file --- Readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 34d04b0..f00d045 100755 --- a/Readme.md +++ b/Readme.md @@ -20,6 +20,9 @@ Android Library for Custom Switches. 5. Added option the disable touch during animation - setInterruptAnimation (only from code) + 6. Added Animation listener to track toggle position in percentages + - setOnAnimateListener (only from code) + ### Developed by [Angad Singh](https://www.github.com/angads25) ([@angads25](https://www.twitter.com/angads25)) @@ -100,4 +103,4 @@ Add it in your root build.gradle at the end of repositories: 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. \ No newline at end of file + limitations under the License.