Android中的脉动按钮动画

10

我正在使用语音识别应用程序,并希望在录制时使我的播放/停止按钮“跳动”。类似于这样的方式:

enter image description here

我尝试过使用ScaleAnimation来让按钮增大,但当然,它会使所有按钮增大。

   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;
}
所以,我的想法是实现类似于这样的效果,只是在实际按钮后面加上一个alpha。我想知道是否可以通过alpha动画或其他方式来实现,在添加第二个“Alpha按钮”到我的按钮后面之前,使其增长并达到此效果。
2个回答

12

终于找到了解决方案!我重写了onDraw方法并为我的按钮绘制了第一个圆,在我的布尔值为真时,我使用alpha作为背景绘制了第二个圆。形成了一个脉动效果:

 @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();
}

你在 Util.adjustAlpha(mColor, 0.4f) 方法中做什么? - Ashish Tiwari
Util.adjustAlpha(mColor, 0.4f) - 这并没有解释太多,我猜你是想设置一个颜色,但为什么需要一个自定义的方法来设置颜色呢? - Antroid
@Francisco Durdin Garcia:你有什么想法可以在谷歌地图标记上实现同样的功能吗? - user2234
有人可以分享这段代码吗?这将节省很多时间。 - vikrant arankalle

3

使用Jetpack Compose可以更轻松地完成操作,无需自定义视图或画布。

@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){}
    }
}

你可以根据需要进行自定义。在内圈卡片中,您可以添加文本或任何您想要的内容。
我已经创建了一个整体的逐步教程。
您可以在这里查看。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接