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
相关产品推荐
相关产品推荐

