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

Android如何为点击的LinearLayout添加左向右滑动灰色填充效果

按钮交互效果演示

效果说明

你要实现的是按钮点击滑动填充转场效果,属于点击反馈+页面跳转衔接的交互动画:点击按钮后,灰色填充从按钮左侧滑到右侧覆盖整个按钮,填充完成后再启动下一个Activity的滑入动画。你当前用LinearLayout实现按钮的结构不需要大改,就能快速实现这个效果。

现有布局代码

你当前的按钮布局代码如下:

<LinearLayout
        android:id="@+id/stockbtn"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="25sp"
        android:layout_marginRight="25sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="StockButtonClick"
        android:orientation="horizontal"
        android:clickable="true"
        android:background = "@drawable/roundedbutton">
        <ImageView
            android:src="@drawable/warehouse"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:clickable="false"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="25dp"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="16dp"
            android:layout_weight="70"
            android:clickable="false"
            android:text="STOCK"
            android:textColor="@color/gray"
            android:textSize="18dp"
            android:textStyle="bold" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/purchasebtn"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="25sp"
        android:layout_marginRight="25sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="purchaseButtonClick"
        android:orientation="horizontal"
        android:clickable="true"
        android:background = "@drawable/roundedbutton">
        <ImageView
            android:src="@drawable/online_pharmacy"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:clickable="false"/>

        <TextView
            android:id="@+id/purchaseText"
            android:layout_width="0dp"
            android:layout_height="25dp"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="16dp"
            android:layout_weight="70"
            android:clickable="false"
            android:text="PURCHASE"
            android:textColor="@color/gray"
            android:textSize="18dp"
            android:textStyle="bold" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/debitnotebtn"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="25sp"
        android:layout_marginRight="25sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="debitnoteButtonClick"
        android:orientation="horizontal"
        android:clickable="true"
        android:background = "@drawable/roundedbutton">
        <ImageView
            android:src="@drawable/payment_method"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:clickable="false"/>

        <TextView

            android:layout_width="0dp"
            android:layout_height="25dp"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="16dp"
            android:layout_weight="70"
            android:clickable="false"
            android:text="DEBIT NOTE"
            android:textColor="@color/gray"
            android:textSize="18dp"
            android:textStyle="bold" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/itemcheck"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="25sp"
        android:layout_marginRight="25sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="itemcheckButtonClick"
        android:orientation="horizontal"
        android:clickable="true"
        android:background = "@drawable/roundedbutton">
        <ImageView
            android:src="@drawable/laptop"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:clickable="false"/>

        <TextView

            android:layout_width="0dp"
            android:layout_height="25dp"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="16dp"
            android:layout_weight="70"
            android:clickable="false"
            android:text="ITEM CHECK"
            android:textColor="@color/gray"
            android:textSize="18dp"
            android:textStyle="bold" />
    </LinearLayout>
实现步骤
  • 核心逻辑:给每个作为按钮的LinearLayout加一个和按钮圆角一致的灰色覆盖层,初始宽度为0、左对齐,点击时用属性动画让覆盖层宽度从0增长到按钮全宽,动画结束后再执行Activity跳转。

1. 调整按钮布局

给每个LinearLayout按钮内部新增一个覆盖层View,注意覆盖层要放在原有图标、文字子控件的后面(XML中写在子控件末尾,保证z序在上层),背景使用和原按钮圆角参数完全一致的灰色填充drawable,避免滑动时边缘错位。以stockbtn为例,修改后结构如下:

<LinearLayout
    android:id="@+id/stockbtn"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="25sp"
    android:layout_marginRight="25sp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="StockButtonClick"
    android:orientation="horizontal"
    android:clickable="true"
    android:background="@drawable/roundedbutton">

    <!-- 原有图标、文字控件保持不变 -->
    <ImageView
        android:src="@drawable/warehouse"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:clickable="false"/>
    <TextView
        android:layout_width="0dp"
        android:layout_height="25dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="16dp"
        android:layout_weight="70"
        android:clickable="false"
        android:text="STOCK"
        android:textColor="@color/gray"
        android:textSize="18dp"
        android:textStyle="bold" />

    <!-- 新增滑动填充覆盖层 -->
    <View
        android:id="@+id/cover_view"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="@drawable/roundedbutton_gray"
        android:clickable="false"/>
</LinearLayout>

注:roundedbutton_gray直接复制你原有的roundedbutton资源,把填充色替换为需要的灰色即可,圆角参数不要修改。

2. 封装通用动画方法

写一个通用方法处理填充动画,避免每个按钮重复写逻辑,以Kotlin为例:

// 动画时长建议设置200-300ms,和后续Activity转场时长匹配即可
private const val FILL_ANIM_DURATION = 250L

private fun runBtnFillAnim(btn: LinearLayout, onAnimEnd: () -> Unit) {
    val coverView = btn.findViewById<View>(R.id.cover_view)
    // 重置覆盖层初始状态
    coverView.layoutParams.width = 0
    coverView.requestLayout()

    btn.post {
        val btnWidth = btn.width
        val anim = ValueAnimator.ofInt(0, btnWidth).apply {
            duration = FILL_ANIM_DURATION
            interpolator = LinearInterpolator()
            addUpdateListener {
                coverView.layoutParams.width = it.animatedValue as Int
                coverView.requestLayout()
            }
            addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    onAnimEnd()
                    // 动画执行完重置覆盖层,避免返回页面时按钮保持灰色
                    coverView.layoutParams.width = 0
                    coverView.requestLayout()
                }
            })
        }
        anim.start()
    }
}

如果用Java开发,逻辑完全一致,换成Java的属性动画写法即可。

3. 修改点击事件逻辑

把原有点击事件里直接跳转Activity的逻辑,放到动画结束的回调里执行即可,比如原有的StockButtonClick方法修改为:

fun StockButtonClick(view: View) {
    runBtnFillAnim(view as LinearLayout) {
        // 这里放你原有的页面跳转逻辑
        startActivity(Intent(this, StockActivity::class.java))
        // 如果需要填充动画和页面滑入效果无缝衔接,可以自定义转场动画替换系统默认
        // overridePendingTransition(R.anim.slide_in_from_right, 0)
    }
}

其余三个按钮的点击事件按同样方式修改即可。

可选优化

如果项目里这类按钮很多,可以自定义一个继承LinearLayout的通用按钮控件,在控件内部自动添加覆盖层、处理点击动画,后续使用时直接引用自定义控件即可,不需要每个布局都手动加覆盖层、重复写动画逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 00:45:39