在 Android 触摸事件中看不到点击波纹效应
Can't see click ripple effect in Android Touch events
我在这里看到了一些解决方案,但是 none 对我有用。我正在使用 View.OnTouchListener
class 来检测我的应用程序代码中的点击和拖动事件。但是那个美丽的涟漪效应现在消失了(也许是因为我在 MotionEvent
手势到达 View.OnClickListener
之前消耗了它。请注意 MotionEvent.ACTION_DOWN
块中的 return true
)。
我无法使用 View.OnClickListener
来检测点击事件,因为我的应用程序使用多个复合手势(点击、点击-按住、点击-按住-拖动等)。任何人都可以分享一些关于如何使用 Android 触摸手势创建涟漪效果的建议吗?
这是我的 View.OnTouchListener
在 BaseAdapter
class 中实现的代码片段:
v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if(mAppActionDownListener != null) {
mAppActionDownListener.onAppActionDown(appObjectList.get(position), v);
}
Log.d("COOK", "ACTION_DOWN: " + ev.getX() + ", " + ev.getY());
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
Log.d("COOK", "ACTION_UP: " + ev.getX() + ", " + ev.getY());
t2 = System.currentTimeMillis();
if(Math.abs(t2-t1) <=300) {
//Toast.makeText(context, "Click event", Toast.LENGTH_SHORT).show();
if(mAppClickListener!=null) {
mAppClickListener.onAppClicked(appObjectList.get(position), v);
}
}
return false;
case MotionEvent.ACTION_MOVE:
Log.d("COOK", "ACTION_MOVE: " + ev.getX() + ", " + ev.getY());
ClipData.Item item = new ClipData.Item(appObjectList.get(position).getAppname()+"~"+appObjectList.get(position).getPackagename()+"~"+appObjectList.get(position).getAppicon());
ClipData dragData = new ClipData(
(CharSequence) v.getTag(),
new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN},
item);
v.findViewById(R.id.appicondrawable).startDrag(dragData, // the data to be dragged
new View.DragShadowBuilder(v.findViewById(R.id.appicondrawable)), // the drag shadow builder
null, // no need to use local data
0 // flags (not currently used, set to 0)
);
if(mAppDragListener!=null) {
mAppDragListener.onAppDragged(appObjectList.get(position), v);
}
return true;
default:
return false;
}
}
});
如有任何帮助,我们将不胜感激!
更新 1:
澄清一下,由于上述原因,在父自定义布局中设置 background/foreground/clickable 属性无效。我已经尝试过这些解决方案。
更新二:
添加适配器项布局代码。:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true"
android:padding="5sp">
<ImageView
android:id="@+id/appicondrawable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:maxWidth="40dp"
android:maxHeight="40dp"
android:scaleType="fitCenter"
android:layout_marginStart="3dp"
android:src="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/appname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:maxLines="1"
android:text="app name"
android:textAlignment="center"
android:textSize="10sp"
android:textColor="#000000" />
</LinearLayout>
要为您的视图添加涟漪效果,您可以添加 ?attr/selectableItemBackground
作为视图的背景。
<ImageView
android:height="100dp"
android:width="100dp"
android:src="@drawable/crush"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true" />
您需要自定义布局的背景或前景。
创建一个名为 res/drawable/ripple_selector.xml
:
的文件
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask"><color android:color="#dcffffff"/></item>
</ripple>
然后,将其用作background
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/ripple_selector"
android:focusable="true"
android:clickable="true"
android:padding="5sp">
...
</LinearLayout>
如果不起作用,请尝试将其用作 foreground
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:foreground="@drawable/ripple_selector"
android:focusable="true"
android:clickable="true"
android:padding="5sp">
...
</LinearLayout>
我找到了解决这个问题的方法。虽然涟漪效应不可定制,但修复非常巧妙。我在 ACTION_DOWN
和 ACTION_UP
事件中手动调用 View
上的 setPressed()
方法,现在我可以看到默认的 Android 涟漪效应。
case MotionEvent.ACTION_DOWN:
//icon.setColorFilter(Color.argb(80, 0, 0, 0));
v.setPressed(true);
if(mAppActionDownListener != null) {
mAppActionDownListener.onAppActionDown(appObjectList.get(position), v);
}
Log.d("COOK", "ACTION_DOWN: " + ev.getX() + ", " + ev.getY());
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
v.setPressed(false);
Log.d("COOK", "ACTION_UP: " + ev.getX() + ", " + ev.getY());
t2 = System.currentTimeMillis();
if(Math.abs(t2-t1) <=300) {
//Toast.makeText(context, "Click event", Toast.LENGTH_SHORT).show();
if(mAppClickListener!=null) {
mAppClickListener.onAppClicked(appObjectList.get(position), v);
}
}
我在这里看到了一些解决方案,但是 none 对我有用。我正在使用 View.OnTouchListener
class 来检测我的应用程序代码中的点击和拖动事件。但是那个美丽的涟漪效应现在消失了(也许是因为我在 MotionEvent
手势到达 View.OnClickListener
之前消耗了它。请注意 MotionEvent.ACTION_DOWN
块中的 return true
)。
我无法使用 View.OnClickListener
来检测点击事件,因为我的应用程序使用多个复合手势(点击、点击-按住、点击-按住-拖动等)。任何人都可以分享一些关于如何使用 Android 触摸手势创建涟漪效果的建议吗?
这是我的 View.OnTouchListener
在 BaseAdapter
class 中实现的代码片段:
v.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if(mAppActionDownListener != null) {
mAppActionDownListener.onAppActionDown(appObjectList.get(position), v);
}
Log.d("COOK", "ACTION_DOWN: " + ev.getX() + ", " + ev.getY());
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
Log.d("COOK", "ACTION_UP: " + ev.getX() + ", " + ev.getY());
t2 = System.currentTimeMillis();
if(Math.abs(t2-t1) <=300) {
//Toast.makeText(context, "Click event", Toast.LENGTH_SHORT).show();
if(mAppClickListener!=null) {
mAppClickListener.onAppClicked(appObjectList.get(position), v);
}
}
return false;
case MotionEvent.ACTION_MOVE:
Log.d("COOK", "ACTION_MOVE: " + ev.getX() + ", " + ev.getY());
ClipData.Item item = new ClipData.Item(appObjectList.get(position).getAppname()+"~"+appObjectList.get(position).getPackagename()+"~"+appObjectList.get(position).getAppicon());
ClipData dragData = new ClipData(
(CharSequence) v.getTag(),
new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN},
item);
v.findViewById(R.id.appicondrawable).startDrag(dragData, // the data to be dragged
new View.DragShadowBuilder(v.findViewById(R.id.appicondrawable)), // the drag shadow builder
null, // no need to use local data
0 // flags (not currently used, set to 0)
);
if(mAppDragListener!=null) {
mAppDragListener.onAppDragged(appObjectList.get(position), v);
}
return true;
default:
return false;
}
}
});
如有任何帮助,我们将不胜感激!
更新 1:
澄清一下,由于上述原因,在父自定义布局中设置 background/foreground/clickable 属性无效。我已经尝试过这些解决方案。
更新二:
添加适配器项布局代码。:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true"
android:padding="5sp">
<ImageView
android:id="@+id/appicondrawable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:maxWidth="40dp"
android:maxHeight="40dp"
android:scaleType="fitCenter"
android:layout_marginStart="3dp"
android:src="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/appname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:maxLines="1"
android:text="app name"
android:textAlignment="center"
android:textSize="10sp"
android:textColor="#000000" />
</LinearLayout>
要为您的视图添加涟漪效果,您可以添加 ?attr/selectableItemBackground
作为视图的背景。
<ImageView
android:height="100dp"
android:width="100dp"
android:src="@drawable/crush"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true" />
您需要自定义布局的背景或前景。
创建一个名为 res/drawable/ripple_selector.xml
:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask"><color android:color="#dcffffff"/></item>
</ripple>
然后,将其用作background
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/ripple_selector"
android:focusable="true"
android:clickable="true"
android:padding="5sp">
...
</LinearLayout>
如果不起作用,请尝试将其用作 foreground
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/applayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:foreground="@drawable/ripple_selector"
android:focusable="true"
android:clickable="true"
android:padding="5sp">
...
</LinearLayout>
我找到了解决这个问题的方法。虽然涟漪效应不可定制,但修复非常巧妙。我在 ACTION_DOWN
和 ACTION_UP
事件中手动调用 View
上的 setPressed()
方法,现在我可以看到默认的 Android 涟漪效应。
case MotionEvent.ACTION_DOWN:
//icon.setColorFilter(Color.argb(80, 0, 0, 0));
v.setPressed(true);
if(mAppActionDownListener != null) {
mAppActionDownListener.onAppActionDown(appObjectList.get(position), v);
}
Log.d("COOK", "ACTION_DOWN: " + ev.getX() + ", " + ev.getY());
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
v.setPressed(false);
Log.d("COOK", "ACTION_UP: " + ev.getX() + ", " + ev.getY());
t2 = System.currentTimeMillis();
if(Math.abs(t2-t1) <=300) {
//Toast.makeText(context, "Click event", Toast.LENGTH_SHORT).show();
if(mAppClickListener!=null) {
mAppClickListener.onAppClicked(appObjectList.get(position), v);
}
}