Timeline: remove reaction animation views for now

This commit is contained in:
ganfra 2021-09-09 18:25:20 +02:00
parent 9914fb2d0f
commit 2144bb9d49
2 changed files with 11 additions and 235 deletions

View File

@ -15,27 +15,18 @@
*/ */
package im.vector.app.features.reactions.widget package im.vector.app.features.reactions.widget
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context import android.content.Context
import android.content.res.TypedArray
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity
import android.view.View import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator import android.widget.LinearLayout
import android.view.animation.DecelerateInterpolator
import android.view.animation.OvershootInterpolator
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.withStyledAttributes import androidx.core.content.withStyledAttributes
import im.vector.app.EmojiCompatWrapper import im.vector.app.EmojiCompatWrapper
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.di.HasScreenInjector
import im.vector.app.core.utils.DimensionConverter
import im.vector.app.core.utils.TextUtils import im.vector.app.core.utils.TextUtils
import im.vector.app.databinding.ReactionButtonBinding import im.vector.app.databinding.ReactionButtonBinding
import javax.inject.Inject import javax.inject.Inject
@ -47,7 +38,7 @@ import javax.inject.Inject
class ReactionButton @JvmOverloads constructor(context: Context, class ReactionButton @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0) defStyleAttr: Int = 0)
: ConstraintLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener { : LinearLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener {
init { init {
if (context is HasScreenInjector) { if (context is HasScreenInjector) {
@ -55,21 +46,11 @@ class ReactionButton @JvmOverloads constructor(context: Context,
} }
} }
companion object {
private val DECCELERATE_INTERPOLATOR = DecelerateInterpolator()
private val ACCELERATE_DECELERATE_INTERPOLATOR = AccelerateDecelerateInterpolator()
private val OVERSHOOT_INTERPOLATOR = OvershootInterpolator(4f)
}
@Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper @Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper
private val views: ReactionButtonBinding private val views: ReactionButtonBinding
var reactedListener: ReactedListener? = null var reactedListener: ReactedListener? = null
private var dotPrimaryColor: Int = 0
private var dotSecondaryColor: Int = 0
private var circleStartColor: Int = 0
private var circleEndColor: Int = 0
var reactionCount = 11 var reactionCount = 11
set(value) { set(value) {
@ -85,50 +66,24 @@ class ReactionButton @JvmOverloads constructor(context: Context,
views.reactionText.text = emojiSpanned views.reactionText.text = emojiSpanned
} }
private var animationScaleFactor: Float = 0.toFloat()
private var isChecked: Boolean = false private var isChecked: Boolean = false
private var animatorSet: AnimatorSet? = null
private var onDrawable: Drawable? = null private var onDrawable: Drawable? = null
private var offDrawable: Drawable? = null private var offDrawable: Drawable? = null
init { init {
inflate(context, R.layout.reaction_button, this) inflate(context, R.layout.reaction_button, this)
orientation = HORIZONTAL
minimumHeight = DimensionConverter(context.resources).dpToPx(30)
gravity = Gravity.CENTER
views = ReactionButtonBinding.bind(this) views = ReactionButtonBinding.bind(this)
views.reactionCount.text = TextUtils.formatCountToShortDecimal(reactionCount) views.reactionCount.text = TextUtils.formatCountToShortDecimal(reactionCount)
// emojiView?.typeface = this.emojiTypeFace ?: Typeface.DEFAULT
context.withStyledAttributes(attrs, R.styleable.ReactionButton, defStyleAttr) { context.withStyledAttributes(attrs, R.styleable.ReactionButton, defStyleAttr) {
onDrawable = ContextCompat.getDrawable(context, R.drawable.reaction_rounded_rect_shape) onDrawable = ContextCompat.getDrawable(context, R.drawable.reaction_rounded_rect_shape)
offDrawable = ContextCompat.getDrawable(context, R.drawable.reaction_rounded_rect_shape_off) offDrawable = ContextCompat.getDrawable(context, R.drawable.reaction_rounded_rect_shape_off)
circleStartColor = getColor(R.styleable.ReactionButton_circle_start_color, 0)
if (circleStartColor != 0) {
views.circle.startColor = circleStartColor
}
circleEndColor = getColor(R.styleable.ReactionButton_circle_end_color, 0)
if (circleEndColor != 0) {
views.circle.endColor = circleEndColor
}
dotPrimaryColor = getColor(R.styleable.ReactionButton_dots_primary_color, 0)
dotSecondaryColor = getColor(R.styleable.ReactionButton_dots_secondary_color, 0)
if (dotPrimaryColor != 0 && dotSecondaryColor != 0) {
views.dots.setColors(dotPrimaryColor, dotSecondaryColor)
}
getString(R.styleable.ReactionButton_emoji)?.let { getString(R.styleable.ReactionButton_emoji)?.let {
reactionString = it reactionString = it
} }
reactionCount = getInt(R.styleable.ReactionButton_reaction_count, 0) reactionCount = getInt(R.styleable.ReactionButton_reaction_count, 0)
val status = getBoolean(R.styleable.ReactionButton_toggled, false) val status = getBoolean(R.styleable.ReactionButton_toggled, false)
setChecked(status) setChecked(status)
} }
@ -137,12 +92,6 @@ class ReactionButton @JvmOverloads constructor(context: Context,
setOnLongClickListener(this) setOnLongClickListener(this)
} }
private fun getDrawableFromResource(array: TypedArray, styleableIndexId: Int): Drawable? {
val id = array.getResourceId(styleableIndexId, -1)
return if (-1 != id) ContextCompat.getDrawable(context, id) else null
}
/** /**
* This triggers the entire functionality of the button such as icon changes, * This triggers the entire functionality of the button such as icon changes,
* animations, listeners etc. * animations, listeners etc.
@ -153,164 +102,25 @@ class ReactionButton @JvmOverloads constructor(context: Context,
if (!isEnabled) { if (!isEnabled) {
return return
} }
isChecked = !isChecked isChecked = !isChecked
// icon!!.setImageDrawable(if (isChecked) likeDrawable else unLikeDrawable) // icon!!.setImageDrawable(if (isChecked) likeDrawable else unLikeDrawable)
background = if (isChecked) onDrawable else offDrawable background = if (isChecked) onDrawable else offDrawable
if (isChecked) { if (isChecked) {
reactedListener?.onReacted(this) reactedListener?.onReacted(this)
} else {
reactedListener?.onUnReacted(this)
}
if (animatorSet != null) {
animatorSet!!.cancel()
}
if (isChecked) {
views.reactionText.animate().cancel() views.reactionText.animate().cancel()
views.reactionText.scaleX = 0f views.reactionText.scaleX = 0f
views.reactionText.scaleY = 0f views.reactionText.scaleY = 0f
} else {
views.circle.innerCircleRadiusProgress = 0f reactedListener?.onUnReacted(this)
views.circle.outerCircleRadiusProgress = 0f
views.dots.currentProgress = 0f
animatorSet = AnimatorSet()
val outerCircleAnimator = ObjectAnimator.ofFloat(views.circle, CircleView.OUTER_CIRCLE_RADIUS_PROGRESS, 0.1f, 1f)
outerCircleAnimator.duration = 250
outerCircleAnimator.interpolator = DECCELERATE_INTERPOLATOR
val innerCircleAnimator = ObjectAnimator.ofFloat(views.circle, CircleView.INNER_CIRCLE_RADIUS_PROGRESS, 0.1f, 1f)
innerCircleAnimator.duration = 200
innerCircleAnimator.startDelay = 200
innerCircleAnimator.interpolator = DECCELERATE_INTERPOLATOR
val starScaleYAnimator = ObjectAnimator.ofFloat(views.reactionText, ImageView.SCALE_Y, 0.2f, 1f)
starScaleYAnimator.duration = 350
starScaleYAnimator.startDelay = 250
starScaleYAnimator.interpolator = OVERSHOOT_INTERPOLATOR
val starScaleXAnimator = ObjectAnimator.ofFloat(views.reactionText, ImageView.SCALE_X, 0.2f, 1f)
starScaleXAnimator.duration = 350
starScaleXAnimator.startDelay = 250
starScaleXAnimator.interpolator = OVERSHOOT_INTERPOLATOR
val dotsAnimator = ObjectAnimator.ofFloat(views.dots, DotsView.DOTS_PROGRESS, 0f, 1f)
// .ofFloat<DotsView>(views.dots, DotsView.DOTS_PROGRESS, 0, 1f)
dotsAnimator.duration = 900
dotsAnimator.startDelay = 50
dotsAnimator.interpolator = ACCELERATE_DECELERATE_INTERPOLATOR
animatorSet!!.playTogether(
outerCircleAnimator,
innerCircleAnimator,
starScaleYAnimator,
starScaleXAnimator,
dotsAnimator
)
animatorSet!!.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationCancel(animation: Animator) {
views.circle.innerCircleRadiusProgress = 0f
views.circle.outerCircleRadiusProgress = 0f
views.dots.currentProgress = 0f
views.reactionText.scaleX = 1f
views.reactionText.scaleY = 1f
}
override fun onAnimationEnd(animation: Animator) {
// if (animationEndListener != null) {
// // animationEndListener!!.onAnimationEnd(this@ReactionButton)
// }
}
})
animatorSet!!.start()
} }
} }
/**
* Used to trigger the scale animation that takes places on the
* icon when the button is touched.
*
* @param event
* @return
*/
// override fun onTouchEvent(event: MotionEvent): Boolean {
// if (!isEnabled)
// return true
//
// when (event.action) {
// MotionEvent.ACTION_DOWN ->
// /*
// Commented out this line and moved the animation effect to the action up event due to
// conflicts that were occurring when library is used in sliding type views.
//
// icon.animate().scaleX(0.7f).scaleY(0.7f).setDuration(150).setInterpolator(DECCELERATE_INTERPOLATOR);
// */
// isPressed = true
//
// MotionEvent.ACTION_MOVE -> {
// val x = event.x
// val y = event.y
// val isInside = x > 0 && x < width && y > 0 && y < height
// if (isPressed != isInside) {
// isPressed = isInside
// }
// }
//
// MotionEvent.ACTION_UP -> {
// views.reactionText!!.animate().scaleX(0.7f).scaleY(0.7f).setDuration(150).interpolator = DECCELERATE_INTERPOLATOR
// views.reactionText!!.animate().scaleX(1f).scaleY(1f).interpolator = DECCELERATE_INTERPOLATOR
// if (isPressed) {
// performClick()
// isPressed = false
// }
// }
// MotionEvent.ACTION_CANCEL -> isPressed = false
// }
// return true
// }
override fun onLongClick(v: View?): Boolean { override fun onLongClick(v: View?): Boolean {
reactedListener?.onLongClick(this) reactedListener?.onLongClick(this)
return reactedListener != null return reactedListener != null
} }
/**
* This set sets the colours that are used for the little dots
* that will be exploding once the like button is clicked.
*
* @param primaryColor
* @param secondaryColor
*/
fun setExplodingDotColorsRes(@ColorRes primaryColor: Int, @ColorRes secondaryColor: Int) {
views.dots.setColors(ContextCompat.getColor(context, primaryColor), ContextCompat.getColor(context, secondaryColor))
}
fun setExplodingDotColorsInt(@ColorInt primaryColor: Int, @ColorInt secondaryColor: Int) {
views.dots.setColors(primaryColor, secondaryColor)
}
fun setCircleStartColorRes(@ColorRes circleStartColor: Int) {
this.circleStartColor = ContextCompat.getColor(context, circleStartColor)
views.circle.startColor = this.circleStartColor
}
fun setCircleStartColorInt(@ColorInt circleStartColor: Int) {
this.circleStartColor = circleStartColor
views.circle.startColor = circleStartColor
}
fun setCircleEndColorRes(@ColorRes circleEndColor: Int) {
this.circleEndColor = ContextCompat.getColor(context, circleEndColor)
views.circle.endColor = this.circleEndColor
}
/** /**
* Sets the initial state of the button to liked * Sets the initial state of the button to liked
* or unliked. * or unliked.
@ -327,13 +137,6 @@ class ReactionButton @JvmOverloads constructor(context: Context,
} }
} }
/**
* Sets the factor by which the dots should be sized.
*/
fun setAnimationScaleFactor(animationScaleFactor: Float) {
this.animationScaleFactor = animationScaleFactor
}
interface ReactedListener { interface ReactedListener {
fun onReacted(reactionButton: ReactionButton) fun onReacted(reactionButton: ReactionButton)
fun onUnReacted(reactionButton: ReactionButton) fun onUnReacted(reactionButton: ReactionButton)

View File

@ -7,7 +7,8 @@
android:background="@drawable/reaction_rounded_rect_shape" android:background="@drawable/reaction_rounded_rect_shape"
android:clipChildren="false" android:clipChildren="false"
android:minWidth="44dp" android:minWidth="44dp"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> android:gravity="center"
tools:parentTag="android.widget.LinearLayout">
<!--<View--> <!--<View-->
<!--android:id="@+id/reactionSelector"--> <!--android:id="@+id/reactionSelector"-->
@ -15,25 +16,6 @@
<!--android:layout_height="match_parent"--> <!--android:layout_height="match_parent"-->
<!--android:background="@drawable/rounded_rect_shape" />--> <!--android:background="@drawable/rounded_rect_shape" />-->
<im.vector.app.features.reactions.widget.DotsView
android:id="@+id/dots"
android:layout_width="30dp"
android:layout_height="30dp"
android:clipChildren="false"
app:layout_constraintBottom_toBottomOf="@+id/reactionText"
app:layout_constraintEnd_toEndOf="@+id/reactionText"
app:layout_constraintStart_toStartOf="@+id/reactionText"
app:layout_constraintTop_toTopOf="@+id/reactionText" />
<im.vector.app.features.reactions.widget.CircleView
android:id="@+id/circle"
android:layout_width="14dp"
android:layout_height="14dp"
app:layout_constraintBottom_toBottomOf="@+id/reactionText"
app:layout_constraintEnd_toEndOf="@+id/reactionText"
app:layout_constraintStart_toStartOf="@+id/reactionText"
app:layout_constraintTop_toTopOf="@+id/reactionText" />
<TextView <TextView
android:id="@+id/reactionText" android:id="@+id/reactionText"
style="@style/Widget.Vector.TextView.Caption" style="@style/Widget.Vector.TextView.Caption"
@ -46,11 +28,6 @@
android:minWidth="20dp" android:minWidth="20dp"
android:singleLine="true" android:singleLine="true"
android:textColor="@color/emoji_color" android:textColor="@color/emoji_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/reactionCount"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="* Party Parrot Again * 👀" /> tools:text="* Party Parrot Again * 👀" />
<TextView <TextView
@ -67,10 +44,6 @@
app:autoSizeMaxTextSize="14sp" app:autoSizeMaxTextSize="14sp"
app:autoSizeMinTextSize="8sp" app:autoSizeMinTextSize="8sp"
app:autoSizeTextType="uniform" app:autoSizeTextType="uniform"
app:layout_constraintBaseline_toBaselineOf="@id/reactionText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/reactionText"
tools:text="13450" /> tools:text="13450" />
</merge> </merge>