其他分享
首页 > 其他分享> > android – 在不消耗触摸事件的情况下实现listItem onClickListener

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