Android带进度条的Toast视图:实现从左到右的抖动动画
Android Toast从左到右展开动画+进度条实现方案
1. 替换中心展开为从左到右展开动画
原growFromCenter函数以视图中心为缩放支点,要改成从左到右展开,只需调整缩放动画的X轴支点为视图左边缘,以下是两种实现方式:
方式一:基于ScaleAnimation改造
private fun View.growFromLeft( duration: Long, @FloatRange(from = 0.0, to = 1.0) startScaleRatio: Float, endAnimCallback: () -> Unit = {}, ) { // X轴从左边缘(0f)开始缩放,Y轴保持垂直中心不缩放 val growFromLeft = ScaleAnimation( startScaleRatio, 1f, // X轴缩放比例从startRatio到1 1f, 1f, // Y轴保持原尺寸不变(需垂直缩放可改为startRatio到1) Animation.RELATIVE_TO_SELF, 0f, // X轴支点:视图左边缘 Animation.RELATIVE_TO_SELF, 0.5f // Y轴支点:视图垂直中心 ) growFromLeft.duration = duration growFromLeft.fillAfter = true growFromLeft.interpolator = FastOutSlowInInterpolator() growFromLeft.setAnimationListener(object : Animation.AnimationListener { override fun onAnimationStart(p0: Animation?) = Unit override fun onAnimationEnd(p0: Animation?) = endAnimCallback.invoke() override fun onAnimationRepeat(p0: Animation?) = Unit }) startAnimation(growFromLeft) }
方式二:基于ObjectAnimator实现(更灵活)
private fun View.expandFromLeft(duration: Long, endAnimCallback: () -> Unit = {}) { pivotX = 0f // 固定缩放支点为视图左边缘 scaleX = 0f // 初始宽度为0 ObjectAnimator.ofFloat(this, "scaleX", 0f, 1f).apply { this.duration = duration interpolator = FastOutSlowInInterpolator() addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator?) = Unit override fun onAnimationEnd(animation: Animator?) = endAnimCallback.invoke() override fun onAnimationCancel(animation: Animator?) = Unit override fun onAnimationRepeat(animation: Animator?) = Unit }) start() } }
2. 与进度条结合的解决方案
方案一:展开完成后启动进度条
确保Toast完全展开后再开始进度倒计时,避免动画冲突:
// 调用示例 toastView.expandFromLeft(300) { val progressBar = toastView.findViewById<ProgressBar>(R.id.toast_progress) // 进度条从100倒转到0,模拟倒计时 ObjectAnimator.ofInt(progressBar, "progress", 100, 0).apply { duration = 2000 // 进度条持续时长 interpolator = LinearInterpolator() start() } }
方案二:同步展开与进度条动画
若需要两个动画同时执行,用AnimatorSet组合控制:
private fun startCombinedAnimations(toastView: View, progressBar: ProgressBar) { // 从左到右展开动画 val expandAnim = ObjectAnimator.ofFloat(toastView, "scaleX", 0f, 1f).apply { pivotX = 0f duration = 300 interpolator = FastOutSlowInInterpolator() } // 进度条动画(总时长=展开时长+停留时长) val progressAnim = ObjectAnimator.ofInt(progressBar, "progress", 0, 100).apply { duration = 2300 interpolator = LinearInterpolator() } // 组合动画:同时启动 AnimatorSet().apply { play(expandAnim).with(progressAnim) start() } }
3. 添加抖动效果
在展开动画完成后,添加横向抖动动画实现需求:
private fun View.shake(duration: Long = 500) { val shakeAnim = TranslateAnimation(0f, 10f, 0f, 0f).apply { this.duration = duration interpolator = CycleInterpolator(5f) // 抖动循环次数 fillAfter = false } startAnimation(shakeAnim) } // 调用示例 toastView.expandFromLeft(300) { toastView.shake() // 启动进度条... }
内容的提问来源于stack exchange,提问作者Sharan
相关产品推荐
相关产品推荐

