@@ -56,7 +56,7 @@ class LoadingButton @JvmOverloads constructor(
5656
5757 var rippleColor = Color .BLACK
5858 set(value){
59- ripplePaint .color = value
59+ mRipplePaint .color = value
6060 field = value
6161 }
6262
@@ -128,12 +128,12 @@ class LoadingButton @JvmOverloads constructor(
128128 private var mDisabledBgColor = Color .LTGRAY
129129 private var mTextColor = Color .WHITE
130130 private var mDisabledTextColor = Color .DKGRAY
131- private var mRippleAlpha = 0.3f
131+ private var mRippleAlpha = 0.2f
132132
133133 private var mPadding = 6 * mDensity
134134
135135 private val mPaint = Paint ()
136- private val ripplePaint = Paint ()
136+ private val mRipplePaint = Paint ()
137137 private val mStrokePaint = Paint ()
138138 private val mTextPaint = Paint ()
139139 private val mPathEffectPaint = Paint ()
@@ -195,10 +195,10 @@ class LoadingButton @JvmOverloads constructor(
195195 isAntiAlias = true
196196 color = mColorPrimary
197197 style = Paint .Style .FILL
198- setShadowDepth(context, 1 )
198+ setShadowDepth(2 * mDensity )
199199 }
200200
201- ripplePaint .apply {
201+ mRipplePaint .apply {
202202 isAntiAlias = true
203203 color = rippleColor
204204 alpha = (mRippleAlpha * 255 ).toInt()
@@ -235,6 +235,8 @@ class LoadingButton @JvmOverloads constructor(
235235 style = Paint .Style .STROKE
236236 strokeWidth = 2 * mDensity
237237 }
238+
239+ setLayerType(LAYER_TYPE_SOFTWARE , mPaint)
238240 }
239241
240242 override fun onMeasure (widthMeasureSpec : Int , heightMeasureSpec : Int ) {
@@ -272,16 +274,18 @@ class LoadingButton @JvmOverloads constructor(
272274 MotionEvent .ACTION_DOWN -> {
273275 mTouchX = event.x
274276 mTouchY = event.y
275- playRippleAnimation( true )
277+ playTouchDownAnimation( )
276278 }
277279 MotionEvent .ACTION_UP -> if (event.x > mButtonRectF.left && event.x < mButtonRectF.right && event.y > mButtonRectF.top && event.y < mButtonRectF.bottom) {
278280 // only register as click if finger is up inside view
279- playRippleAnimation(false )
281+ playRippleAnimation()
280282 } else {
281283 // if finger is moved outside view and lifted up, reset view
282284 mTouchX = 0f
283285 mTouchY = 0f
284286 mRippleRadius = 0f
287+ mRipplePaint.alpha = (mRippleAlpha * 255 ).toInt()
288+ mPaint.setShadowDepth(2 * mDensity)
285289 invalidate()
286290 }
287291 }
@@ -301,7 +305,7 @@ class LoadingButton @JvmOverloads constructor(
301305 canvas.drawText(mText, (width - mTextWidth) / 2 , (viewHeight - mTextHeight) / 2 + mPadding * 2 , mTextPaint)
302306 if ((mTouchX > 0 || mTouchY > 0 ) && rippleEnable) {
303307 canvas.clipRect(0f , mPadding, width.toFloat(), viewHeight - mPadding)
304- canvas.drawCircle(mTouchX, mTouchY, mRippleRadius, ripplePaint )
308+ canvas.drawCircle(mTouchX, mTouchY, mRippleRadius, mRipplePaint )
305309 }
306310 }
307311 }
@@ -471,29 +475,51 @@ class LoadingButton @JvmOverloads constructor(
471475 invalidate()
472476 }
473477
474-
475- private fun playRippleAnimation (isTouchDown : Boolean ) {
476- mPaint.setShadowDepth(context, 2 )
477- ValueAnimator .ofFloat(
478- if (isTouchDown) 0f else (width / 2 ).toFloat(),
479- if (isTouchDown) (width / 2 ).toFloat() else width.toFloat())
478+ private fun playTouchDownAnimation (){
479+ ValueAnimator .ofFloat(0f , 1f )
480480 .apply {
481481 duration = 240
482482 interpolator = AccelerateDecelerateInterpolator ()
483483 addUpdateListener { valueAnimator ->
484- mRippleRadius = valueAnimator.animatedValue as Float
484+ val progress = valueAnimator.animatedValue as Float
485+ mPaint.setShadowDepth((2 + 4 * progress) * mDensity)
486+ mRippleRadius = width * progress
487+ // mRipplePaint.alpha = (255 * mRippleAlpha * (1 - progress)).toInt()
485488 invalidate()
486489 }
487- if (! isTouchDown) doOnEnd {
488- performClick()
489- mTouchX = 0f
490- mTouchY = 0f
491- mRippleRadius = 0f
490+ }
491+ .start()
492+ }
493+
494+
495+ private fun playRippleAnimation () {
496+ ValueAnimator .ofFloat(
497+ 1f ,
498+ 0f )
499+ .apply {
500+ duration = 240
501+ interpolator = DecelerateInterpolator ()
502+ addUpdateListener { valueAnimator ->
503+ val progress = valueAnimator.animatedValue as Float
504+ mRipplePaint.alpha = (255 * mRippleAlpha * progress).toInt()
505+ mPaint.setShadowDepth((2 + 4 * progress) * mDensity)
492506 invalidate()
493507 }
508+ doOnEnd {
509+ doClick()
510+ }
494511 }.start()
495512 }
496513
514+ private fun doClick (){
515+ mTouchX = 0f
516+ mTouchY = 0f
517+ mRipplePaint.alpha = (mRippleAlpha * 255 ).toInt()
518+ mRippleRadius = 0f
519+ invalidate()
520+ performClick()
521+ }
522+
497523 private fun playStartAnimation (isReverse : Boolean ) {
498524 val viewHeight = max(height, mMinHeight.toInt())
499525 val animator = ValueAnimator .ofInt(
@@ -510,7 +536,7 @@ class LoadingButton @JvmOverloads constructor(
510536 doOnEnd {
511537 mCurrentState = if (isReverse) STATE_BUTTON else STATE_ANIMATION_STEP2
512538 if (mCurrentState == STATE_BUTTON ) {
513- mPaint.setShadowDepth(context, 1 )
539+ mPaint.setShadowDepth(2 * mDensity )
514540 invalidate()
515541 }
516542 }
@@ -708,7 +734,6 @@ private fun Animator.doOnEnd(action: (animator: Animator?) -> Unit) {
708734 })
709735}
710736
711- private fun Paint.setShadowDepth (context : Context ,depth : Int ){
712- val density = context.resources.displayMetrics.density
713- this .setShadowLayer(depth * density, 0f , 2 * density, 0x1F000000 )
737+ private fun Paint.setShadowDepth (depth : Float ){
738+ this .setShadowLayer(depth, 0f , 2f , 0x6F000000 .toInt())
714739}
0 commit comments