You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android按钮长按动画实现方案咨询(Android 7及以上)

嘿,我来帮你搞定Android按钮的长按动画!针对Android 7及以上版本,有两种简单高效的实现方式,你可以根据自己的需求来选:

方式一:用XML定义状态动画(StateListAnimator)

这种方式适合不需要复杂逻辑的场景,完全通过XML配置按钮在不同状态下的动画,系统会自动处理状态切换,省心又省力。

步骤1:创建动画配置文件

在res/animator目录下新建一个XML文件(如果没有animator目录就自己创建),比如命名为button_long_press_animator.xml,写入以下内容:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 按压(长按按住)状态:按钮缩小+提升Z轴高度 -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator
                android:duration="150"
                android:propertyName="scaleX"
                android:valueTo="0.95"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="150"
                android:propertyName="scaleY"
                android:valueTo="0.95"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="150"
                android:propertyName="translationZ"
                android:valueTo="4dp"
                android:valueType="floatType" />
        </set>
    </item>
    <!-- 默认状态:松开后恢复原样 -->
    <item>
        <set>
            <objectAnimator
                android:duration="150"
                android:propertyName="scaleX"
                android:valueTo="1.0"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="150"
                android:propertyName="scaleY"
                android:valueTo="1.0"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="150"
                android:propertyName="translationZ"
                android:valueTo="2dp"
                android:valueType="floatType" />
        </set>
    </item>
</selector>

步骤2:在布局中引用动画

找到你的按钮布局,添加android:stateListAnimator属性关联刚才的动画文件,还可以加上Material Design的波纹效果让体验更棒:

<Button
    android:id="@+id/my_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="长按我试试"
    android:stateListAnimator="@animator/button_long_press_animator"
    <!-- 可选:添加Material波纹效果 -->
    android:background="?attr/selectableItemBackground" />
方式二:代码中通过触摸监听实现自定义动画

如果需要更灵活的逻辑(比如长按超过指定时间才触发动画、结合其他操作),就用这种方式,完全由你控制动画的触发时机和行为。

Kotlin示例代码

val myButton = findViewById<Button>(R.id.my_button)
var longPressTimer: Timer? = null

// 定义缩小动画
val scaleDownAnim = ViewPropertyAnimator.ofPropertyValuesHolder(
    myButton,
    PropertyValuesHolder.ofFloat("scaleX", 0.9f),
    PropertyValuesHolder.ofFloat("scaleY", 0.9f)
).setDuration(200)

// 定义恢复动画
val scaleUpAnim = ViewPropertyAnimator.ofPropertyValuesHolder(
    myButton,
    PropertyValuesHolder.ofFloat("scaleX", 1.0f),
    PropertyValuesHolder.ofFloat("scaleY", 1.0f)
).setDuration(200)

myButton.setOnTouchListener { v, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            // 按下后启动定时器,500ms后触发长按动画(可自定义延迟时间)
            longPressTimer = Timer().apply {
                schedule(object : TimerTask() {
                    override fun run() {
                        runOnUiThread {
                            scaleDownAnim.start()
                        }
                    }
                }, 500)
            }
            true
        }
        MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
            // 松开或取消操作时,取消定时器并恢复按钮状态
            longPressTimer?.cancel()
            longPressTimer = null
            scaleUpAnim.start()
            true
        }
        else -> false
    }
}

Java示例代码

Button myButton = findViewById(R.id.my_button);
Timer longPressTimer = null;

// 定义缩小动画
ViewPropertyAnimator scaleDownAnim = ViewPropertyAnimator.ofPropertyValuesHolder(
        myButton,
        PropertyValuesHolder.ofFloat("scaleX", 0.9f),
        PropertyValuesHolder.ofFloat("scaleY", 0.9f)
).setDuration(200);

// 定义恢复动画
ViewPropertyAnimator scaleUpAnim = ViewPropertyAnimator.ofPropertyValuesHolder(
        myButton,
        PropertyValuesHolder.ofFloat("scaleX", 1.0f),
        PropertyValuesHolder.ofFloat("scaleY", 1.0f)
).setDuration(200);

myButton.setOnTouchListener((v, event) -> {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            longPressTimer = new Timer();
            longPressTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    runOnUiThread(() -> scaleDownAnim.start());
                }
            }, 500);
            return true;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            if (longPressTimer != null) {
                longPressTimer.cancel();
                longPressTimer = null;
            }
            scaleUpAnim.start();
            return true;
        default:
            return false;
    }
});

一些小提示

  • 动画时长:建议设置在150-200ms之间,既流畅又不会显得拖沓。
  • 波纹效果:搭配?attr/selectableItemBackground或?attr/selectableItemBackgroundBorderless,可以让按钮的按压反馈更符合Material Design风格。
  • 兼容性:Android 7及以上版本完全支持这两种方式,不用担心适配问题。

内容的提问来源于stack exchange,提问作者AndroidExpert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:36:09