android – 在不消耗触摸事件的情况下实现listItem onClickListener
作者:互联网
我正在尝试实现一个允许滑动和单击按钮的自定义列表视图,类似于回旋镖电子邮件客户端已实现的实现(或适用于iOS的Mailbox).
如果我只想单击列表项本身,我可以创建一个新的OnItemClickListener,并确保没有可聚焦或可点击的后代,这些后代不会消耗触摸事件,并允许自定义列表视图检测滑动.但是,如果我在列表项中单击任何内容,它将使用触摸事件,而不是调用OnItemClickListener,并禁用自定义列表本身的滑动功能.
我已经尝试创建onTouchListener的自定义实现,或者使用onInterceptTouchEvent来创建自定义视图组.对于所有这些实现,onTouchListener必须在Action.DOWN上返回true(因此消耗触摸事件)否则它将停止监听触摸事件的其余部分.
为什么OnItemClickListener可以在不消耗触摸事件的情况下检测触摸,以及如何为我自己的自定义实现复制它?任何帮助或指针赞赏!
这是OnItemClickListener,它可以工作并且不使用触摸事件:
private AdapterView.OnItemClickListener onClick = new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> adapterView, View v, int position,
long arg3) {
mAction = mAdapter.getItem(position);
updateListToShowCurrentAction();
return;
}
};
这是我希望能够为列表项中的视图实现的功能,同时仍将触摸事件传递到自定义列表视图:
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = mListView.getPositionForView((View) v.getParent());
mReordCtrl.removeAction(mAdapter, position);
}
});
这是list_item中的布局代码段:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="list_item" >
<LinearLayout
android:id="@+id/back"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal"
android:tag="back" >
<ImageView
android:id="@+id/cancel_button"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:src="@drawable/ic_action_cancel"
android:tag="cancel_button" />
</LinearLayout>
解决方法:
如果您已经使用onInterceptTouchEvent,请尝试覆盖onTouchEvent(MotionEvent e).这是一个可以适应您需求的示例实现,它集成了一个SimpleOnGestureListener检测器和一个可用于回调父类的自定义接口viewListener.如果您只想检测点击次数,则可能不需要所有这些;你可能只能逃脱手势探测器.另外,这是我在研究触摸事件处理时发现的有用的link.
@Override public boolean onTouchEvent(MotionEvent ev) {
//See if the gesture detector has detected an event.
boolean eventConsumed = detector.onTouchEvent(ev);
if (!eventConsumed) {
//If no gesture detected, and the motion is finished, do something
if (ev.getAction() == MotionEvent.ACTION_UP) {
//DO SOMETHING, such as scroll
//Send event to listener.
if (viewListener != null) {
this.viewListener.onUp(ev.getX());
}
return true; //Consume the event, so nothing else fires.
} else {
//If no event is detected, and the action hasn't finished, do the default behavior
return super.onTouchEvent(ev);
}
} else {
return true; //Consume the event, so nothing else fires. You can change this to false if you'd like to not consume the event.
}
}
和,一个自定义垂直滚动视图类,捕获向下滑动,但将所有其他手势传递给孩子.
public class VerticalScrollView extends ScrollView {
private GestureDetector mGestureDetector;
View.OnTouchListener mGestureListener;
public VerticalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new YScrollDetector());
setFadingEdgeLength(0);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean superBool = super.onInterceptTouchEvent(ev);
boolean intercept = mGestureDetector.onTouchEvent(ev);
return superBool && intercept ;
}
// Return false if we're scrolling more in the x direction than in the y direction, so we don't claim the action.
class YScrollDetector extends SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return Math.abs(distanceY) > Math.abs(distanceX);
}
}
}
标签:gesture-recognition,android,android-listview,touch-event 来源: https://codeday.me/bug/20190831/1773704.html