diff options
author | Thomas <tschneider.ac@gmail.com> | 2023-01-13 16:19:50 +0100 |
---|---|---|
committer | Thomas <tschneider.ac@gmail.com> | 2023-01-13 16:19:50 +0100 |
commit | 107ac13e1547c50424497f29116d1aaf9bc6ab69 (patch) | |
tree | e7f37e97b66858ef8e42183937fc22ec16daa027 | |
parent | d70c285beaf058f8817dffc04b980f9c3cb93e31 (diff) |
Fix issue #745 - Update library for bottom buttons.
21 files changed, 865 insertions, 35 deletions
diff --git a/app/build.gradle b/app/build.gradle index eaabe38d4..63041b029 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,7 +78,7 @@ allprojects { } dependencies { implementation project(':autoimageslider') - implementation 'androidx.appcompat:appcompat:1.5.1' + implementation 'androidx.appcompat:appcompat:1.6.0' implementation 'com.google.android.material:material:1.7.0' @@ -94,7 +94,6 @@ dependencies { implementation "org.conscrypt:conscrypt-android:2.5.2" implementation 'com.vanniktech:emoji-one:0.6.0' implementation 'com.github.GrenderG:Toasty:1.5.2' - implementation 'org.framagit.tom79:SparkButton:1.0.13' implementation "com.github.bumptech.glide:glide:4.14.2" implementation "com.github.bumptech.glide:okhttp3-integration:4.14.2" implementation("com.github.bumptech.glide:recyclerview-integration:4.14.2") { @@ -107,7 +106,7 @@ dependencies { implementation 'com.github.mergehez:ArgPlayer:v3.1' implementation project(path: ':mytransl') implementation project(path: ':ratethisapp') - + implementation project(path: ':sparkbutton') implementation 'com.burhanrashid52:photoeditor:1.5.1' implementation("com.vanniktech:android-image-cropper:4.3.3") diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java index ca686c881..450473b35 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java @@ -638,21 +638,13 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> } - holder.binding.actionButtonFavorite.pressOnTouch(false); - holder.binding.actionButtonBoost.pressOnTouch(false); - holder.binding.actionButtonBookmark.pressOnTouch(false); + holder.binding.actionButtonFavorite.setActiveImage(R.drawable.ic_round_star_24); holder.binding.actionButtonFavorite.setInactiveImage(R.drawable.ic_round_star_border_24); holder.binding.actionButtonBookmark.setActiveImage(R.drawable.ic_round_bookmark_24); holder.binding.actionButtonBookmark.setInactiveImage(R.drawable.ic_round_bookmark_border_24); holder.binding.actionButtonBoost.setActiveImage(R.drawable.ic_round_repeat_24); holder.binding.actionButtonBoost.setInactiveImage(R.drawable.ic_round_repeat_24); - holder.binding.actionButtonFavorite.setDisableCircle(true); - holder.binding.actionButtonBoost.setDisableCircle(true); - holder.binding.actionButtonBookmark.setDisableCircle(true); - holder.binding.actionButtonFavorite.setActiveImageTint(R.color.marked_icon); - holder.binding.actionButtonBoost.setActiveImageTint(R.color.boost_icon); - holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon); applyColor(context, holder); if (status.pinned) { @@ -2319,9 +2311,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> Helper.changeDrawableColor(context, R.drawable.ic_bot, theme_icons_color); Helper.changeDrawableColor(context, R.drawable.ic_round_reply_24, theme_icons_color); Helper.changeDrawableColor(context, holder.binding.actionButtonTranslate, theme_icons_color); - holder.binding.actionButtonFavorite.setInActiveImageTintColor(theme_icons_color); - holder.binding.actionButtonBookmark.setInActiveImageTintColor(theme_icons_color); - holder.binding.actionButtonBoost.setInActiveImageTintColor(theme_icons_color); holder.binding.replyCount.setTextColor(theme_icons_color); } if (theme_statuses_color != -1) { diff --git a/app/src/main/res/drawable/ic_round_bookmark_24.xml b/app/src/main/res/drawable/ic_round_bookmark_24.xml index fdc2c64d4..f8e4675ec 100644 --- a/app/src/main/res/drawable/ic_round_bookmark_24.xml +++ b/app/src/main/res/drawable/ic_round_bookmark_24.xml @@ -1,7 +1,7 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:tint="?attr/colorControlNormal" + android:tint="@color/marked_icon" android:viewportWidth="24" android:viewportHeight="24"> <path diff --git a/app/src/main/res/drawable/ic_round_repeat_active_24.xml b/app/src/main/res/drawable/ic_round_repeat_active_24.xml new file mode 100644 index 000000000..75e67ce56 --- /dev/null +++ b/app/src/main/res/drawable/ic_round_repeat_active_24.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="@color/boost_icon" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="?attr/colorControlNormal" + android:pathData="M7,7h10v1.79c0,0.45 0.54,0.67 0.85,0.35l2.79,-2.79c0.2,-0.2 0.2,-0.51 0,-0.71l-2.79,-2.79c-0.31,-0.31 -0.85,-0.09 -0.85,0.36L17,5L6,5c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1L7,7zM17,17L7,17v-1.79c0,-0.45 -0.54,-0.67 -0.85,-0.35l-2.79,2.79c-0.2,0.2 -0.2,0.51 0,0.71l2.79,2.79c0.31,0.31 0.85,0.09 0.85,-0.36L7,19h11c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v3z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_round_star_24.xml b/app/src/main/res/drawable/ic_round_star_24.xml index 3421678ad..335e3bd84 100644 --- a/app/src/main/res/drawable/ic_round_star_24.xml +++ b/app/src/main/res/drawable/ic_round_star_24.xml @@ -1,7 +1,7 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:tint="?attr/colorControlNormal" + android:tint="@color/marked_icon" android:viewportWidth="24" android:viewportHeight="24"> <path diff --git a/app/src/main/res/layout/drawer_status.xml b/app/src/main/res/layout/drawer_status.xml index 443a3e57d..4c062eee6 100644 --- a/app/src/main/res/layout/drawer_status.xml +++ b/app/src/main/res/layout/drawer_status.xml @@ -17,6 +17,7 @@ <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" + xmlns:sparkbutton="http://schemas.android.com/apk/res-auto" android:id="@+id/cardview_container" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -655,12 +656,11 @@ android:layout_height="48dp" android:adjustViewBounds="true" android:contentDescription="@string/reblog_add" - app:sparkbutton_activeImage="@drawable/ic_round_repeat_24" - app:sparkbutton_animationSpeed="1.5" - app:sparkbutton_iconSize="24dp" - app:sparkbutton_inActiveImage="@drawable/ic_round_repeat_24" - app:sparkbutton_primaryColor="@color/boost_icon" - app:sparkbutton_secondaryColor="@color/boost_icon" /> + app:activeImage="@drawable/ic_round_repeat_active_24" + app:iconSize="28dp" + app:inactiveImage="@drawable/ic_round_repeat_24" + app:primaryColor="@color/boost_icon" + app:secondaryColor="@color/boost_icon" /> <androidx.appcompat.widget.AppCompatImageButton android:id="@+id/action_button_quote" @@ -691,12 +691,12 @@ android:layout_gravity="center" android:adjustViewBounds="true" android:contentDescription="@string/favourite_add" - app:sparkbutton_activeImage="@drawable/ic_round_star_24" - app:sparkbutton_animationSpeed="1.5" - app:sparkbutton_iconSize="24dp" - app:sparkbutton_inActiveImage="@drawable/ic_round_star_border_24" - app:sparkbutton_primaryColor="@color/marked_icon" - app:sparkbutton_secondaryColor="@color/marked_icon" /> + app:activeImage="@drawable/ic_round_star_24" + app:animationSpeed="1.5" + app:inactiveImage="@drawable/ic_round_star_border_24" + app:primaryColor="@color/marked_icon" + app:secondaryColor="@color/marked_icon" + sparkbutton:iconSize="28dp" /> <com.varunest.sparkbutton.SparkButton android:id="@+id/action_button_bookmark" @@ -709,12 +709,12 @@ android:layout_gravity="center" android:adjustViewBounds="true" android:contentDescription="@string/bookmark_add" - app:sparkbutton_activeImage="@drawable/ic_round_bookmark_24" - app:sparkbutton_animationSpeed="1.5" - app:sparkbutton_iconSize="24dp" - app:sparkbutton_inActiveImage="@drawable/ic_round_bookmark_border_24" - app:sparkbutton_primaryColor="@color/marked_icon" - app:sparkbutton_secondaryColor="@color/marked_icon" /> + app:activeImage="@drawable/ic_round_bookmark_24" + app:animationSpeed="1.5" + app:inactiveImage="@drawable/ic_round_bookmark_border_24" + app:primaryColor="@color/marked_icon" + app:secondaryColor="@color/marked_icon" + sparkbutton:iconSize="28dp" /> <androidx.appcompat.widget.AppCompatImageButton diff --git a/settings.gradle b/settings.gradle index eea69bc0f..a2ba1bfb8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,3 +3,4 @@ include ':app' include ':autoimageslider' include ':mytransl' include ':ratethisapp' +include ':sparkbutton' diff --git a/sparkbutton/.gitignore b/sparkbutton/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/sparkbutton/.gitignore @@ -0,0 +1 @@ +/build diff --git a/sparkbutton/build.gradle b/sparkbutton/build.gradle new file mode 100644 index 000000000..54d8db901 --- /dev/null +++ b/sparkbutton/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.library' + +group = 'com.github.tom79' + +android { + compileSdkVersion 33 + + defaultConfig { + minSdkVersion 15 + targetSdkVersion 33 + versionCode 3 + versionName "1.0.12" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions { + abortOnError false + } +} +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.6.0' +} diff --git a/sparkbutton/gradle.properties b/sparkbutton/gradle.properties new file mode 100644 index 000000000..89a05eff9 --- /dev/null +++ b/sparkbutton/gradle.properties @@ -0,0 +1,3 @@ +POM_NAME=SparkButton +POM_ARTIFACT_ID=sparkbutton +POM_PACKAGING=aar
\ No newline at end of file diff --git a/sparkbutton/maven-push.gradle b/sparkbutton/maven-push.gradle new file mode 100644 index 000000000..8ebb6959b --- /dev/null +++ b/sparkbutton/maven-push.gradle @@ -0,0 +1,96 @@ +apply plugin: 'maven' +apply plugin: 'signing' + +def isReleaseBuild() { + return VERSION_NAME.contains("SNAPSHOT") == false +} + +def getReleaseRepositoryUrl() { + return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL + : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" +} + +def getSnapshotRepositoryUrl() { + return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL + : "https://oss.sonatype.org/content/repositories/snapshots/" +} + +def getRepositoryUsername() { + return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" +} + +def getRepositoryPassword() { + return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" +} + +afterEvaluate { project -> + uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + pom.groupId = GROUP + pom.artifactId = POM_ARTIFACT_ID + pom.version = VERSION_NAME + + repository(url: getReleaseRepositoryUrl()) { + authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) + } + snapshotRepository(url: getSnapshotRepositoryUrl()) { + authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) + } + + pom.project { + name POM_NAME + packaging POM_PACKAGING + description POM_DESCRIPTION + url POM_URL + + scm { + url POM_SCM_URL + connection POM_SCM_CONNECTION + developerConnection POM_SCM_DEV_CONNECTION + } + + licenses { + license { + name POM_LICENCE_NAME + url POM_LICENCE_URL + distribution POM_LICENCE_DIST + } + } + + developers { + developer { + id POM_DEVELOPER_ID + name POM_DEVELOPER_NAME + } + } + } + } + } + } + + signing { + required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } + sign configurations.archives + } + + //task androidJavadocs(type: Javadoc) { + //source = android.sourceSets.main.allJava + //} + + //task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { + //classifier = 'javadoc' + //from androidJavadocs.destinationDir + //} + + task androidSourcesJar(type: Jar) { + classifier = 'sources' + from android.sourceSets.main.java.sourceFiles + } + + artifacts { + archives androidSourcesJar + } +}
\ No newline at end of file diff --git a/sparkbutton/proguard-rules.pro b/sparkbutton/proguard-rules.pro new file mode 100644 index 000000000..5407790ba --- /dev/null +++ b/sparkbutton/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/sparkbutton/src/main/AndroidManifest.xml b/sparkbutton/src/main/AndroidManifest.xml new file mode 100644 index 000000000..1f76ffe6a --- /dev/null +++ b/sparkbutton/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ +<manifest package="com.varunest.sparkbutton"> + + <application /> +</manifest> diff --git a/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkButton.java b/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkButton.java new file mode 100644 index 000000000..19787c5b8 --- /dev/null +++ b/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkButton.java @@ -0,0 +1,313 @@ +package com.varunest.sparkbutton; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Build; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.OvershootInterpolator; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; +import androidx.annotation.Px; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.core.content.ContextCompat; + +import com.varunest.sparkbutton.helpers.SparkAnimationView; +import com.varunest.sparkbutton.helpers.Utils; + +/** + * @author varun 7th July 2016 + */ +public class SparkButton extends FrameLayout implements View.OnClickListener { + private static final DecelerateInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator(); + private static final AccelerateDecelerateInterpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator(); + private static final OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4); + + private static final int INVALID_RESOURCE_ID = -1; + private static final float ANIMATIONVIEW_SIZE_FACTOR = 3; + private static final float DOTS_SIZE_FACTOR = .08f; + int activeImageTint; + int inActiveImageTint; + private @DrawableRes + int imageResourceIdActive = INVALID_RESOURCE_ID; + private @DrawableRes + int imageResourceIdInactive = INVALID_RESOURCE_ID; + private @Px + int imageSize; + private @ColorInt + int primaryColor; + private @ColorInt + int secondaryColor; + private SparkAnimationView sparkAnimationView; + private ImageView imageView; + private float animationSpeed = 1; + private boolean isChecked = false; + private AnimatorSet animatorSet; + private SparkEventListener listener; + + SparkButton(Context context) { + super(context); + } + + public SparkButton(Context context, AttributeSet attrs) { + super(context, attrs); + initFromXML(attrs); + init(); + } + + public SparkButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initFromXML(attrs); + init(); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public SparkButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + initFromXML(attrs); + init(); + } + + + void init() { + int animationViewSize = (int) (imageSize * ANIMATIONVIEW_SIZE_FACTOR); + + sparkAnimationView = new SparkAnimationView(getContext()); + LayoutParams dotsViewLayoutParams = new LayoutParams(animationViewSize, animationViewSize, Gravity.CENTER); + sparkAnimationView.setLayoutParams(dotsViewLayoutParams); + + sparkAnimationView.setColors(secondaryColor, primaryColor); + sparkAnimationView.setMaxDotSize((int) (imageSize * DOTS_SIZE_FACTOR)); + + addView(sparkAnimationView); + + imageView = new AppCompatImageView(getContext()); + LayoutParams imageViewLayoutParams = new LayoutParams(imageSize, imageSize, Gravity.CENTER); + imageView.setLayoutParams(imageViewLayoutParams); + + addView(imageView); + + if (imageResourceIdInactive != INVALID_RESOURCE_ID) { + // should load inactive img first + imageView.setImageResource(imageResourceIdInactive); + } else if (imageResourceIdActive != INVALID_RESOURCE_ID) { + imageView.setImageResource(imageResourceIdActive); + } else { + throw new IllegalArgumentException("One of Inactive/Active Image Resources is required!"); + } + setOnTouchListener(); + setOnClickListener(this); + } + + /** + * Call this function to start spark animation + */ + public void playAnimation() { + if (animatorSet != null) { + animatorSet.cancel(); + } + + imageView.animate().cancel(); + imageView.setScaleX(0); + imageView.setScaleY(0); + sparkAnimationView.setInnerCircleRadiusProgress(0); + sparkAnimationView.setOuterCircleRadiusProgress(0); + sparkAnimationView.setCurrentProgress(0); + + animatorSet = new AnimatorSet(); + + ObjectAnimator outerCircleAnimator = ObjectAnimator.ofFloat(sparkAnimationView, SparkAnimationView.OUTER_CIRCLE_RADIUS_PROGRESS, 0.1f, 1f); + outerCircleAnimator.setDuration((long) (250 / animationSpeed)); + outerCircleAnimator.setInterpolator(DECELERATE_INTERPOLATOR); + + ObjectAnimator innerCircleAnimator = ObjectAnimator.ofFloat(sparkAnimationView, SparkAnimationView.INNER_CIRCLE_RADIUS_PROGRESS, 0.1f, 1f); + innerCircleAnimator.setDuration((long) (200 / animationSpeed)); + innerCircleAnimator.setStartDelay((long) (200 / animationSpeed)); + innerCircleAnimator.setInterpolator(DECELERATE_INTERPOLATOR); + + ObjectAnimator starScaleYAnimator = ObjectAnimator.ofFloat(imageView, ImageView.SCALE_Y, 0.2f, 1f); + starScaleYAnimator.setDuration((long) (350 / animationSpeed)); + starScaleYAnimator.setStartDelay((long) (250 / animationSpeed)); + starScaleYAnimator.setInterpolator(OVERSHOOT_INTERPOLATOR); + + ObjectAnimator starScaleXAnimator = ObjectAnimator.ofFloat(imageView, ImageView.SCALE_X, 0.2f, 1f); + starScaleXAnimator.setDuration((long) (350 / animationSpeed)); + starScaleXAnimator.setStartDelay((long) (250 / animationSpeed)); + starScaleXAnimator.setInterpolator(OVERSHOOT_INTERPOLATOR); + + ObjectAnimator dotsAnimator = ObjectAnimator.ofFloat(sparkAnimationView, SparkAnimationView.DOTS_PROGRESS, 0, 1f); + dotsAnimator.setDuration((long) (900 / animationSpeed)); + dotsAnimator.setStartDelay((long) (50 / animationSpeed)); + dotsAnimator.setInterpolator(ACCELERATE_DECELERATE_INTERPOLATOR); + + animatorSet.playTogether( + outerCircleAnimator, + innerCircleAnimator, + starScaleYAnimator, + starScaleXAnimator, + dotsAnimator + ); + + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + sparkAnimationView.setInnerCircleRadiusProgress(0); + sparkAnimationView.setOuterCircleRadiusProgress(0); + sparkAnimationView.setCurrentProgress(0); + imageView.setScaleX(1); + imageView.setScaleY(1); + } + + @Override + public void onAnimationEnd(Animator animation) { + } + + @Override + public void onAnimationStart(Animator animation) { + } + }); + + animatorSet.start(); + } + + + public @Px + int getImageSize() { + return imageSize; + } + + public void setImageSize(@Px int imageSize) { + this.imageSize = imageSize; + } + + public @ColorInt + int getPrimaryColor() { + return primaryColor; + } + + public void setPrimaryColor(@ColorInt int primaryColor) { + this.primaryColor = primaryColor; + } + + public @ColorInt + int getSecondaryColor() { + return secondaryColor; + } + + public void setSecondaryColor(@ColorInt int secondaryColor) { + this.secondaryColor = secondaryColor; + } + + public void setAnimationSpeed(float animationSpeed) { + this.animationSpeed = animationSpeed; + } + + /** + * @return Returns whether the button is checked (Active) or not. + */ + public boolean isChecked() { + return isChecked; + } + + /** + * Change Button State (Works only if both active and disabled image resource is defined) + * + * @param flag desired checked state of the button + */ + public void setChecked(boolean flag) { + isChecked = flag; + imageView.setImageResource(isChecked ? imageResourceIdActive : imageResourceIdInactive); + } + + public void setInactiveImage(int inactiveResource) { + this.imageResourceIdInactive = inactiveResource; + imageView.setImageResource(isChecked ? imageResourceIdActive : imageResourceIdInactive); + } + + public void setActiveImage(int activeResource) { + this.imageResourceIdActive = activeResource; + imageView.setImageResource(isChecked ? imageResourceIdActive : imageResourceIdInactive); + } + + @Override + public void onClick(View v) { + boolean shouldPlayAnimation = listener == null || listener.onEvent(this, isChecked); + + if (shouldPlayAnimation) { + if (imageResourceIdInactive != INVALID_RESOURCE_ID) { + isChecked = !isChecked; + + imageView.setImageResource(isChecked ? imageResourceIdActive : imageResourceIdInactive); + + if (animatorSet != null) { + animatorSet.cancel(); + } + if (isChecked) { + sparkAnimationView.setVisibility(VISIBLE); + playAnimation(); + } else { + sparkAnimationView.setVisibility(INVISIBLE); + } + } else { + playAnimation(); + } + } + } + + + private void setOnTouchListener() { + setOnTouchListener((v, event) -> { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + imageView.animate().scaleX(0.8f).scaleY(0.8f).setDuration(150).setInterpolator(DECELERATE_INTERPOLATOR); + setPressed(true); + break; + + case MotionEvent.ACTION_MOVE: + break; + + case MotionEvent.ACTION_UP: + imageView.animate().scaleX(1).scaleY(1).setInterpolator(DECELERATE_INTERPOLATOR); + if (isPressed()) { + performClick(); + setPressed(false); + } + break; + + case MotionEvent.ACTION_CANCEL: + imageView.animate().scaleX(1).scaleY(1).setInterpolator(DECELERATE_INTERPOLATOR); + break; + } + return true; + }); + } + + private int getColor(int id) { + return ContextCompat.getColor(getContext(), id); + } + + + private void initFromXML(AttributeSet attr) { + TypedArray a = getContext().obtainStyledAttributes(attr, R.styleable.SparkButton); + imageSize = a.getDimensionPixelOffset(R.styleable.SparkButton_iconSize, Utils.dpToPx(getContext(), 50)); + imageResourceIdActive = a.getResourceId(R.styleable.SparkButton_activeImage, INVALID_RESOURCE_ID); + imageResourceIdInactive = a.getResourceId(R.styleable.SparkButton_inactiveImage, INVALID_RESOURCE_ID); + primaryColor = ContextCompat.getColor(getContext(), a.getResourceId(R.styleable.SparkButton_primaryColor, R.color.spark_primary_color)); + secondaryColor = ContextCompat.getColor(getContext(), a.getResourceId(R.styleable.SparkButton_secondaryColor, R.color.spark_secondary_color)); + animationSpeed = a.getFloat(R.styleable.SparkButton_animationSpeed, 1); + // recycle typedArray + a.recycle(); + } +} diff --git a/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkButtonBuilder.java b/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkButtonBuilder.java new file mode 100644 index 000000000..f79e492e8 --- /dev/null +++ b/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkButtonBuilder.java @@ -0,0 +1,61 @@ +package com.varunest.sparkbutton; + +import android.content.Context; + +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; + +import com.varunest.sparkbutton.helpers.Utils; + +/** + * @author varun on 07/07/16. + */ +public class SparkButtonBuilder { + private final SparkButton sparkButton; + private final Context context; + + public SparkButtonBuilder(Context context) { + this.context = context; + sparkButton = new SparkButton(context); + } + + public SparkButtonBuilder setActiveImage(@DrawableRes int resourceId) { + sparkButton.setActiveImage(resourceId); + return this; + } + + public SparkButtonBuilder setInactiveImage(@DrawableRes int resourceId) { + sparkButton.setInactiveImage(resourceId); + return this; + } + + public SparkButtonBuilder setPrimaryColor(@ColorInt int color) { + sparkButton.setPrimaryColor(color); + return this; + } + + public SparkButtonBuilder setSecondaryColor(int color) { + sparkButton.setSecondaryColor(color); + return this; + } + + public SparkButtonBuilder setImageSizePx(int px) { + sparkButton.setImageSize(px); + return this; + } + + public SparkButtonBuilder setImageSizeDp(int dp) { + sparkButton.setImageSize(Utils.dpToPx(context, dp)); + return this; + } + + public SparkButtonBuilder setAnimationSpeed(float speed) { + sparkButton.setAnimationSpeed(speed); + return this; + } + + public SparkButton build() { + sparkButton.init(); + return sparkButton; + } +} diff --git a/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkEventListener.java b/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkEventListener.java new file mode 100644 index 000000000..2e02b0891 --- /dev/null +++ b/sparkbutton/src/main/java/com/varunest/sparkbutton/SparkEventListener.java @@ -0,0 +1,10 @@ +package com.varunest.sparkbutton; + +import androidx.annotation.NonNull; + +/** + * @author varun on 07/07/16. |