Android利用layer-list实现的按钮按动效果

tech2022-11-07  132

按钮按动效果由三部分组成:按压前背景图、按压后背景图、文字位置的变化

按压前背景图:使用layer-list,在主背景下叠加一层颜色图片,通过设置left/top/right/bottom使其立体

<!--distance、corners这里分别为5dp、10dp,具体可以自定--> <!--可以变更具体的偏移方向以使其向不同方向立体--> <layer-list> <item android:top="@dimen/distance" android:left="@dimen/distance"> <shape> <solid android:color="#779E9E9E"/> <corners android:radius="@dimen/corners"/> </shape> </item> <item android:bottom="@dimen/distance" android:right="@dimen/distance"> <shape> <solid android:color="@color/blue"/> <corners android:radius="@dimen/corners"/> </shape> </item> </layer-list>

按压后背景图:将按压前背景中设置的偏移方向全部反过来(原来top的改为bottom、原来left的改为right,其余同理),并将主背景下的颜色图片改为透明,同时也可将主背景的颜色换成淡色的,使效果更好

<layer-list> <item android:bottom="@dimen/distance" android:right="@dimen/distance"> <shape> <solid android:color="@android:color/transparent"/> <corners android:radius="@dimen/corners"/> </shape> </item> <item android:top="@dimen/distance" android:left="@dimen/distance"> <shape> <solid android:color="#81D4FA"/> <corners android:radius="@dimen/corners"/> </shape> </item> </layer-list>

然后就可以用selector将其组装起来应用到按钮的背景

<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="false"> <!--按压前背景图--> </item> <item android:state_pressed="true"> <!--按压后背景图--> </item> </selector>

到此,对于无文字的按钮而言,便已经可以了

控制文字位置变化:对按钮而言,整个视觉上的三维实则为为它的二维背景,所以文字并不会处于主背景的中间(这一点,你可通过在按钮的原有内边距基础上,在加上你在相应方向上设置的distance以使其在主背景居中),同时,文字也不会随着主背景的位置变化而变化位置,所以对有文字按钮,需动态的更改文字位置(这里通过动态变化文字内边距来实现,也许有更好的方法)

在按钮的点击中,有多种过程:

DOWN -> UP(简单的点击)DOWN -> MOVE(没有移出按钮) -> UP(按下后稍微移动了一下再抬起)DOWN -> MOVE(移出了按钮)(按下后移出了按钮)

故具体的设计思路是:复写按钮所在Activity的dispatchTouchEvent方法,首先检查一次事件中是否发生在了按钮上,若是,则在DOWN事件中将文字设置为按压后的内边距,在UP事件中将文字设置为按压前的内边距;若不是,则在MOVE事件将文字设置为按压前的内边距,同时将按钮的按压状态设置为false,即取消按钮的按压状态。

// needRestore是初值为false的一个boolean变量,用来避免多次执行MOVE事件中的代码 // 10dp为我的按钮原本设置的内边距,5dp为layer-list中设置的distance,15dp即两者之和 @Override public boolean dispatchTouchEvent(MotionEvent ev) { int[] leftAndTop = new int[2];// [left, top] button.getLocationInWindow(leftAndTop); // 检查是否发生在按钮上 if (ev.getX() >= leftAndTop[0] && ev.getX() <= (leftAndTop[0] + button.getWidth()/*right*/) && ev.getY() >= leftAndTop[1] && ev.getY() <= (leftAndTop[1] + button.getHeight()/*bottom*/)) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: needRestore = true; button.setPadding(fromDpToPx(15), fromDpToPx(5), fromDpToPx(10), 0); break; case MotionEvent.ACTION_UP: needRestore = false; button.setPadding(fromDpToPx(10), 0, fromDpToPx(15), fromDpToPx(5)); break; } } else { if (needRestore) { needRestore = false; button.setPadding(fromDpToPx(10), 0, fromDpToPx(15), fromDpToPx(5)); button.setPressed(false); } } return super.dispatchTouchEvent(ev); }

能力所限,不足之处烦请多多指教!

最新回复(0)