Pulsating button animation in Android
Asked Answered
P

2

11

I'm working with a Voice recognition application and I want to make my play/stop button "pulse" when it's recording. Something like this:

enter image description here

I have tried to make a ScaleAnimation, doing the button grow, but of course, it makes grow all the button.

   public static ObjectAnimator pulseAnimation(ImageView target){

    ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(target,
            PropertyValuesHolder.ofFloat("scaleX", 1.1f),
            PropertyValuesHolder.ofFloat("scaleY", 1.1f));
    scaleDown.setDuration(310);
    scaleDown.setRepeatCount(ObjectAnimator.INFINITE);
    scaleDown.setRepeatMode(ObjectAnimator.REVERSE);

    return scaleDown;
}

So the idea is achieve something like that but just with a alpha behind the actual button. I want to know if it's possible to do this with an alpha animation or something before add a second "Alpha Button" behind my button to make it grow and achieve this effect.

Prudential answered 16/5, 2016 at 21:9 Comment(0)
P
12

Finally I found the solution! I overrided the onDraw method and draw a first circle for my button and, when my boolean is true. I draw a second circle with an alpha as a background. Making a pulsating effect:

 @Override
protected void onDraw(Canvas canvas) {

    int w = getMeasuredWidth();
    int h = getMeasuredHeight();
    mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mCirclePaint.setColor(mColor);
    mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mBackgroundPaint.setColor(Util.adjustAlpha(mColor, 0.4f));
    //Draw circle
    canvas.drawCircle(w/2, h/2, MIN_RADIUS_VALUE , mCirclePaint);        
    if (mAnimationOn) {
        if (mRadius >= MAX_RADIUS_VALUE)
            mPaintGoBack = true;
        else if(mRadius <= MIN_RADIUS_VALUE)
            mPaintGoBack = false;
        //Draw pulsating shadow
        canvas.drawCircle(w / 2, h / 2, mRadius, mBackgroundPaint);
        mRadius = mPaintGoBack ? (mRadius - 0.5f) : (mRadius + 0.5f);
        invalidate();
    }

    super.onDraw(canvas);
}
 public void animateButton(boolean animate){
    if (!animate)
        mRadius = MIN_RADIUS_VALUE;
    mAnimationOn = animate;
    invalidate();
}
Prudential answered 23/5, 2016 at 22:19 Comment(4)
What are you doing in Util.adjustAlpha(mColor, 0.4f) methodLoathe
Util.adjustAlpha(mColor, 0.4f) - doesnt really explains much ,all i can guess is you are trying to set a color to it, but why you need a custom method to set the color?Breach
@Francisco Durdin Garcia: any idea how we can do the same on a google map marker ?Headboard
can anybody share this code it will save lot more timeLederhosen
E
3

With Jetpack Compose it's much easier to do No custom views or canvas needed

@Composable
fun PulseLoading(
    durationMillis:Int = 1000,
    maxPulseSize:Float = 300f,
    minPulseSize:Float = 50f,
    pulseColor:Color = Color(234,240,246),
    centreColor:Color =  Color(66,133,244)
){
    val infiniteTransition = rememberInfiniteTransition()
    val size by infiniteTransition.animateFloat(
        initialValue = minPulseSize,
        targetValue = maxPulseSize,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis, easing = LinearEasing),
            repeatMode = RepeatMode.Restart
        )
    )
    val alpha by infiniteTransition.animateFloat(
        initialValue = 1f,
        targetValue = 0f,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis, easing = LinearEasing),
            repeatMode = RepeatMode.Restart
        )
    )
    Box(contentAlignment = Alignment.Center,modifier = Modifier.fillMaxSize()) {
//Card for Pulse Effect
        Card(
            shape = CircleShape,
            modifier = Modifier.size(size.dp).align(Alignment.Center).alpha(alpha),
            backgroundColor = pulseColor,
            elevation = 0.dp
        ) {}
//Card For inner circle
        Card(modifier = Modifier
            .size(minPulseSize.dp)
            .align(Alignment.Center),
            shape = CircleShape,
            backgroundColor = centreColor){}
    }
}

You can customize it according to your needs. and in the Inner circle card, you can add text or anything you want.

I have created a whole step by step tutorial on this You can check it out here.

Evangelistic answered 12/8, 2021 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.