Android 实现工具栏菜单项单击涟漪效果
我尝试使用Android 实现工具栏菜单项单击涟漪效果,android,android-layout,android-view,android-drawable,rippledrawable,Android,Android Layout,Android View,Android Drawable,Rippledrawable,我尝试使用填充来增加按钮的触摸区域。我用 <ImageButton android:paddingRight="32dp" android:paddingEnd="32dp" android:id="@+id/confirm_image_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignPar
填充
来增加按钮的触摸区域。我用
<ImageButton
android:paddingRight="32dp"
android:paddingEnd="32dp"
android:id="@+id/confirm_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="?selectableItemBackgroundBorderless"
android:src="?attr/confirmIcon" />
现在,
selectableitemsbackgroundless
圆圈效果是一个完美的圆圈ImageButton
的实际区域时,不会显示圆圈按压效果
我可以知道为什么会这样吗?我怎样才能克服它?我使用API 26进行了测试。
注意,我尽量避免使用TouchDelegate
技术,除非我被迫这样做,因为这会使我们的代码更加复杂
补充资料 以下是
工具栏
按钮显示的正确行为
单击区域位于按钮外部时会显示涟漪效应
单击区域位于按钮内时会显示涟漪效应
然而,我不知道他们是如何实施这种行为的
Android 5.0上的涟漪从每个视图的中心开始。相符合的
根据材料设计规则,涟漪应该从触摸的地方开始
事件发生时,它们似乎从手指向外流动这是
在Android 5.1中解决,但在Android 5.0中是一个bug
要解决此问题,您需要使用添加到
可在API级别21中绘制setHotspot()
为可绘制的
“热点”,而RippleDrawable
显然将其用作涟漪效应的发射点<代码>设置热点()获取一对
浮点值,大概是为了使用sethospot()
在一个OnTouchListener
中,当MotionEvent
报告X/Y
具有浮动值的触摸事件的位置
感谢忙碌的编码员的指南书
您可以使用以下代码更正ripples错误:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
btn.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouch(View v, MotionEvent event) {
v.getBackground()
.setHotspot(event.getX(), event.getY());
return(false);
}
});
}
其他解决方案:
另一个解决方案: 第一次尝试时: 我试着用填充物来增加按钮的触摸面积 您可以使用此代码将波纹中心置于
图像按钮的中心。
:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
btn.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouch(View v, MotionEvent event) {
v.getBackground()
.setHotspot(v.getWidth()/2f, v.getHeight()/2f);//setting hot spot at center of ImageButton
return(false);
}
});
}
当
FrameLayout
包装ImageButton
时,可能还有另一种解决方案:
正如你所说:
然而,它似乎有一些奇怪的行为。当我点击
ImageButton的实际区域,圆圈按压效果未显示
解决此问题的方法可能是在ImageButton的onClick()方法中添加frameLayout.performClick()
或者,当单击ImageButton
时,您可以模拟触摸frameLayout
,如下所示:
// Obtain MotionEvent object
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis() + 100;
float x = 0.0f;// or x = frameLayout.getWidth()/2f
float y = 0.0f;// or y = frameLayout.getHeight()/2f
// List of meta states found here: developer.android.com/reference/android/view/KeyEvent.html#getMetaState()
int metaState = 0;
MotionEvent motionEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_UP,
x,
y,
metaState
);
// Dispatch touch event to view
frameLayout.dispatchTouchEvent(motionEvent);
我怀疑您的问题在于您有一个ImageButton
,而不仅仅是ImageView
。ImageButton
的默认样式为:
<style name="Widget.ImageButton">
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:scaleType">center</item>
<item name="android:background">@android:drawable/btn_default</item>
</style>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:duplicateParentState="true"
android:src="@drawable/ic_check_black_24dp"
/>
另一个是相同的,除了FrameLayout
内的视图是:
<style name="Widget.ImageButton">
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:scaleType">center</item>
<item name="android:background">@android:drawable/btn_default</item>
</style>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:duplicateParentState="true"
android:src="@drawable/ic_check_black_24dp"
/>
以下是视觉证明:
这是在运行Android 5.0.2的模拟器上捕获的。我在我的8.0手机上试用过,效果也不错。如果你使用android:duplicateParentState=“true”
,只需将安卓:clickable=“false”
设置为你的图像按钮
将使你的按钮及其父按钮在点击时高亮显示
<ImageButton
...
android:duplicateParentState="true"
android:clickable="false"
/>
当使用setOnClickListener
时,它也将setClickable(true)
,因此在这种情况下,您只需为其父布局设置setOnClickListener
,花了一些时间后,我终于发现了“工具栏之谜”是如何工作的。工具栏上显示的是ActionMenuItemView
。您可以看到,它内部应用了style=“?attr/actionButtonStyle”
<代码>?attr/actionButtonStyle
对应于此样式,在该样式中我们可以看到?attr/actionBarItemBackground
如果您想对您的ImageButton
应用相同的效果,那么您所要做的就是对其应用android:background=“?attr/actionBarItemBackground”
。因此,具有以下xml布局:
<ImageButton
android:id="@+id/confirm_image_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/actionBarItemBackground"
android:src="@drawable/ic_check_black_24dp" />
因此,您可以创建您的drawable并将其作为ImageButton
的背景应用。我可以知道没有此解决方法它无法工作的原因吗?您是否有关于此错误的参考源?我使用API 26进行测试。我可以确认你提出的解决方案不起作用OnTouchListener
被触发,但圆圈按下效果没有显示。我已经阅读了这些答案,但它没有回答我的疑问。我知道如何实现连锁反应。(正如您所看到的,我的涟漪效应是通过使用中的技术实现的)但我的问题不同,这在我的问题中已经清楚地说明了。@CheokYanCheng在您第一次尝试时,它只有带填充的ImageButton,您可以使用v.getBackground().setHotspot(v.getWidth()/2f,v.getHeight()/2f)代码>将波纹中心定位在图像按钮的中心。请参阅我编辑的答案我建议您编写动画并单击行为。我认为这是最快的解决方案。我尝试将ImageButton
替换为ImageView
。它仍然表现出与我在ImageButton
中描述的相同的问题行为。如果按下的区域在图像视图上
,则不会显示圆形按下效果。@CheokYanCheng手动将可聚焦和可点击设置为假
?另外,您是否在图像或容器上设置了onClickListener
?是和是。我尝试了,并尝试在容器和/或按钮上单击侦听器。(各种组合)。它不起作用。你试过站在你这边吗?“这对你有用吗?”彻盐城说得很好。我已经用实际代码更新了我的答案。也许有什么不对劲
<ImageButton
android:id="@+id/confirm_image_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/actionBarItemBackground"
android:src="@drawable/ic_check_black_24dp" />
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight"
android:radius="20dp" />