Android 在不使用触摸事件的情况下实现listItem onClickListener
我正在尝试实现一个自定义列表视图,该视图允许滑动和单击按钮,类似于boomerang电子邮件客户端(或iOS邮箱)所实现的实现 如果我只想单击列表项本身,我可以创建一个新的OnItemClickListener,并确保没有可聚焦或可单击的子体,这不会消耗触摸事件,并允许自定义列表视图检测滑动。但是,如果我使列表项中的任何内容可单击,它将使用触摸事件,而不是调用OnItemClickListener,并禁用自定义列表本身的滑动功能 我尝试过创建onTouchListener的自定义实现,或者为自定义视图组使用onInterceptTouchEvent。对于所有这些实现,onTouchListener必须在Action.DOWN时返回true(从而使用触摸事件),否则它将停止侦听触摸事件的其余部分 为什么McClickListener可以在不使用触摸事件的情况下检测触摸,我如何为自己的自定义实现复制它?感谢您的帮助和指点 以下是MClickListener,它可以工作,但不使用触摸事件:Android 在不使用触摸事件的情况下实现listItem onClickListener,android,android-listview,touch-event,gesture-recognition,Android,Android Listview,Touch Event,Gesture Recognition,我正在尝试实现一个自定义列表视图,该视图允许滑动和单击按钮,类似于boomerang电子邮件客户端(或iOS邮箱)所实现的实现 如果我只想单击列表项本身,我可以创建一个新的OnItemClickListener,并确保没有可聚焦或可单击的子体,这不会消耗触摸事件,并允许自定义列表视图检测滑动。但是,如果我使列表项中的任何内容可单击,它将使用触摸事件,而不是调用OnItemClickListener,并禁用自定义列表本身的滑动功能 我尝试过创建onTouchListener的自定义实现,或者为自定
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;
}
};
以下是列表项中的布局片段:
<?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。如果你只是想检测点击,你可能不需要所有这些;你也许可以用手势检测器逃过一劫。另外,我在研究触摸事件处理时发现了一个有用的例子
@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);
}
}
}我确信我遗漏了一些东西,因为据我所知,获得整个手势的唯一方法是在动作时返回true.DOWN,从而在知道是触摸还是滑动之前消耗运动事件的其余部分。我们的想法是在列表视图中实现滑动,在列表项目视图中实现触摸,但我研究的时间越长,我越怀疑由于android实现消费触摸事件的方式,这种功能不可能实现。这是完全可能的。我有一个活动,它包括一个顶层垂直滚动视图,其中包含一组可单击的项目(视图和按钮)和一个自定义幻灯片类,该类支持单击和水平滑动。花了一点时间才使它工作起来。我将scroll视图子类化,并使用onScroll手势检测器覆盖InterceptTouchEvent以捕获垂直滚动。所有其他事件都由子级处理,上面的代码是自定义幻灯片类的一部分。我在答案中添加了垂直滚动视图代码,希望对您有所帮助。非常感谢您的帮助!我听从了你的建议,并有一个自定义的父视图来处理所有非点击触摸事件。我仍在努力获得与我正在使用的库相同的功能,但我认为我现在走上了正确的道路。
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);
}
}