ListView 上的 SwipeListener 和 ListView 项目上的 ClickListener [英] SwipeListener on ListView and ClickListener on ListView's items

查看:15
本文介绍了ListView 上的 SwipeListener 和 ListView 项目上的 ClickListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的

我怎样才能摆脱这个问题?我认为这可以通过禁用 ListView 中所有项目的所有点击事件来实现.怎么能这样呢?还有其他办法吗?

我想要在 ListView 上滑动并点击 ListView 的项目.

SwipeDetector.java - 用于检测 ListView 上的滑动

 公共类 SwipeDetector 实现 View.OnTouchListener {私人 SwipeListener swipeListener;私有列表视图 mListView;私人国际百;私有布尔motionInterceptDisallowed = false;公共静态枚举操作{LR,//从左到右RL,//从右到左TB,//从上到下BT,//从下到上无//未找到操作}私有静态最终 int HORIZONTAL_MIN_DISTANCE = 30;//最低//距离为//水平滑动私有静态最终 int VERTICAL_MIN_DISTANCE = 80;//最小距离//垂直//滑动私人浮动 downX、downY、upX、upY;//坐标私人动作 mSwipeDetected = Action.None;//最后一个动作公共 SwipeDetector(上下文上下文,ListView listView){百 = (int) context.getResources().getDimension(R.dimen.hundred);mListView = 列表视图;}公共布尔 swipeDetected() {返回 mSwipeDetected != Action.None;}公共动作 getAction() {返回 mSwipeDetected;}/*** 刷卡检测*/@覆盖公共布尔 onTouch(查看 v,MotionEvent 事件){开关(事件.getAction()){案例 MotionEvent.ACTION_DOWN:{downX = event.getX();downY = event.getY();mSwipeDetected = Action.None;返回假;//允许处理其他事件,例如 Click}案例 MotionEvent.ACTION_MOVE:{upX = event.getX();upY = event.getY();浮动 deltaX = downX - upX;浮动 deltaY = downY - upY;浮点 absX = Math.abs(deltaX);float absY = Math.abs(deltaY);if((absX >= (3 * absY)) && absX > HORIZONTAL_MIN_DISTANCE && mListView != null && !motionInterceptDisallowed) {mListView.requestDisallowInterceptTouchEvent(true);motionInterceptDisallowed = true;}if((absX >= (3 * absY)) && absX <= 百) {如果 (deltaX > 0) {mSwipeDetected = Action.RL;swipeListener.onSwipe(MotionEvent.ACTION_MOVE, Action.RL, absX);}}返回假;}案例 MotionEvent.ACTION_UP:swipeListener.onSwipe(MotionEvent.ACTION_UP, Action.BT, 0);如果(mListView != null){mListView.requestDisallowInterceptTouchEvent(false);motionInterceptDisallowed = false;}返回假;案例 MotionEvent.ACTION_CANCEL:返回真;}返回假;}/*** 设置聊天发送监听器* @param 监听器*/公共无效 setSwipeListener(SwipeListener 监听器) {swipeListener = 监听器;}公共接口 SwipeListener {void onSwipe(int event, Action action, float x);}}

这就是我在 ListView 上设置 SwipeDetector 的方式

final SwipeDetector swipeDetector = new SwipeDetector(SwipeActivity.this, mListView);swipeDetector.setSwipeListener(mSwipeListener);mListView.setOnTouchListener(swipeDetector);

我的Activity实现了SwipeDetector.SwipeListener

下面重写了 onSwipe() 方法

@Overridepublic void onSwipe(int event, SwipeDetector.Action action, float x) {开关(事件){案例 MotionEvent.ACTION_MOVE:System.out.println("列表移动");休息;案例 MotionEvent.ACTION_UP:System.out.println("列出");休息;}}

在我的适配器中,我在 TextView、ImageView 和 VideoView 上设置 onClickListener()

holder.mTextView.setOnClickListener(new View.OnClickListener() {@覆盖public void onClick(View v) {System.out.println("item textview 点击");}});holder.mImageView.setOnClickListener(new View.OnClickListener() {@覆盖public void onClick(View v) {System.out.println("item imageview 点击");}});holder.mVideoView.setOnClickListener(new View.OnClickListener() {@覆盖public void onClick(View v) {System.out.println("item videoview 点击");}});

当我从 ListView 的空白区域开始滑动时,ListView 的滑动监听器会捕获它.但是,当我从 TextView/ImageView/VideoView 开始滑动时,会触发该视图的 onClickListener 而不是父级(ListView 的)onTouchListener().

我该如何实现?我希望当我点击 ListView 的项目时,该项目的 onClick 应该被触发,当我在 ListView 的项目上滑动时,ListView 的 onSwipe 应该被触发.

解决方案

对于 listitemonClickListenerSwipeListener 对于 <代码>列表,因为它在触摸时考虑哪个视图之间存在歧义

您使用实现 onTouchListener

OnSwipeTouchListener

OnSwipeTouchListener.java

import android.view.GestureDetector;导入 android.view.GestureDetector.SimpleOnGestureListener;导入 android.view.MotionEvent;导入 android.view.View;导入 android.view.View.OnTouchListener;公共类 OnSwipeTouchListener 实现 OnTouchListener {私人最终 GestureDetector 手势检测器;公共 OnSwipeTouchListener(上下文 ctx){手势检测器 = 新手势检测器(ctx,新手势监听器());}私有最终类 GestureListener 扩展 SimpleOnGestureListener {私有静态最终 int SWIPE_THRESHOLD = 100;私有静态最终 int SWIPE_VELOCITY_THRESHOLD = 100;@覆盖公共布尔 onDown(MotionEvent e) {返回真;}@覆盖公共布尔onFling(MotionEvent e1,MotionEvent e2,浮动速度X,浮动速度Y){布尔结果 = 假;尝试 {float diffY = e2.getY() - e1.getY();float diffX = e2.getX() - e1.getX();如果 (Math.abs(diffX) > Math.abs(diffY)) {如果 (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {如果 (diffX > 0) {onSwipeRight();} 别的 {onSwipeLeft();}}结果=真;}否则 if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {如果(差异> 0){onSwipeBottom();} 别的 {onSwipeTop();}}结果=真;} catch(异常异常){异常.printStackTrace();}返回结果;}}公共无效 onSwipeRight() {}公共无效 onSwipeLeft() {}公共无效 onSwipeTop() {}公共无效 onSwipeBottom() {}}

并在 listitem

上使用 OnSwipeTouchListener

 listitem.setOnTouchListener(new OnSwipeTouchListener() {公共无效 onSwipeLeft() {//要做列表视图向左滑动的东西Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();}公共布尔 onTouch(查看 v,MotionEvent 事件){//点击列表项时要做的事情返回gestureDetector.onTouchEvent(event);}});});//获取点击事件

This is my old question. However this time I have provided my code as well.

I have a ListView with different types of rows. The row may contain text, image, video or something else. If I click on ImageView (inside the row) I will go to another activity to show the image in full screen, If I click on Video (inside the row) I will go to another activity to play he video.

I have implemented right to left swipe listener on my ListView. If I start the ListView swipe from an empty space in ListView, the swipe works (first and second row in below image). However if I start the ListView swipe from the ListView row's item, then the swipe doesn't work (third and fourth row in below image). If I remove the click events from ImageView and Video then the swipe works even if I start the swipe from the ListView row's item i.e. in this case the swipe works on whole ListView, no matter on which row I do the swipe.

How can I get rid on this problem? I think this can be achieved if I disable all the click events on the all the items inside ListView. How can do so? Is there any other way?

I want both swipe on ListView and click on ListView's item.

SwipeDetector.java - For detecting swipes on the ListView

public class SwipeDetector implements View.OnTouchListener {

private SwipeListener swipeListener;
private ListView mListView;
private int hundred;
private boolean motionInterceptDisallowed = false;

public static enum Action {
    LR, // Left to right
    RL, // Right to left
    TB, // Top to bottom
    BT, // Bottom to top
    None // Action not found
}

private static final int HORIZONTAL_MIN_DISTANCE = 30; // The minimum
// distance for
// horizontal swipe
private static final int VERTICAL_MIN_DISTANCE = 80; // The minimum distance
// for vertical
// swipe
private float downX, downY, upX, upY; // Coordinates
private Action mSwipeDetected = Action.None; // Last action

public SwipeDetector(Context context, ListView listView) {
    hundred = (int) context.getResources().getDimension(R.dimen.hundred);
    mListView = listView;
}

public boolean swipeDetected() {
    return mSwipeDetected != Action.None;
}

public Action getAction() {
    return mSwipeDetected;
}

/**
 * Swipe detection
 */@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        {
            downX = event.getX();
            downY = event.getY();
            mSwipeDetected = Action.None;
            return false; // allow other events like Click to be processed
        }
        case MotionEvent.ACTION_MOVE:
        {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            float absX = Math.abs(deltaX);
            float absY = Math.abs(deltaY);

            if((absX >= (3 * absY)) && absX > HORIZONTAL_MIN_DISTANCE && mListView != null && !motionInterceptDisallowed) {
                mListView.requestDisallowInterceptTouchEvent(true);
                motionInterceptDisallowed = true;
            }

            if((absX >= (3 * absY)) && absX <= hundred) {
                if (deltaX > 0) {
                    mSwipeDetected = Action.RL;
                    swipeListener.onSwipe(MotionEvent.ACTION_MOVE, Action.RL, absX);
                }
            }


            return false;
        }
        case MotionEvent.ACTION_UP:
            swipeListener.onSwipe(MotionEvent.ACTION_UP, Action.BT, 0);
            if (mListView != null) {
                mListView.requestDisallowInterceptTouchEvent(false);
                motionInterceptDisallowed = false;
            }
            return false;
        case MotionEvent.ACTION_CANCEL:
            return true;
    }
    return false;
}

/**
 * Set chat send listener
 * @param listener
 */
public void setSwipeListener(SwipeListener listener) {
    swipeListener = listener;
}

public interface SwipeListener {
    void onSwipe(int event, Action action, float x);
}

}

This is how I am setting SwipeDetector on my ListView

final SwipeDetector swipeDetector = new SwipeDetector(SwipeActivity.this, mListView);
    swipeDetector.setSwipeListener(mSwipeListener);
    mListView.setOnTouchListener(swipeDetector);

My Activity implements SwipeDetector.SwipeListener

Below is overridden onSwipe() method

@Override
public void onSwipe(int event, SwipeDetector.Action action, float x) {
    switch (event) {
            case MotionEvent.ACTION_MOVE:
                System.out.println("list move");
                break;
            case MotionEvent.ACTION_UP:
                System.out.println("list up");
                break;
        }
}

In my adapter I am setting onClickListener() on my TextView, ImageView and VideoView

holder.mTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("item textview click");
        }
    });

holder.mImageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("item imageview click");
        }
    });

holder.mVideoView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("item videoview click");
        }
    });

When I start the swipe from the empty area of ListView, the ListView's swipe listener captures it. However, when I start the swipe from the TextView/ImageView/VideoView then that View's onClickListener is fired instead of parent's (ListView's) onTouchListener().

How can I implement the same? I want that when I click on ListView's item then that item's onClick should get fired and when I swipe on the ListView's item then ListView's onSwipe should get fired.

解决方案

Thats Not Possible with both onClickListener for listitem and SwipeListener for List,because it gets Ambiguity between which View to Consider on touch

You Use OnSwipeTouchListener which implements onTouchListener

OnSwipeTouchListener.java

import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener (Context ctx){
        gestureDetector = new GestureDetector(ctx, new GestureListener());
    }

    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                    }
                    result = true;
                } 
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom();
                        } else {
                            onSwipeTop();
                        }
                    }
                    result = true;

            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public void onSwipeRight() {
    }

    public void onSwipeLeft() {
    }

    public void onSwipeTop() {
    }

    public void onSwipeBottom() {
    }
}

And use OnSwipeTouchListener on listitem

  listitem.setOnTouchListener(new OnSwipeTouchListener() {

        public void onSwipeLeft() {
            //stuff to do list view left swipe 
            Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
        }


        public boolean onTouch(View v, MotionEvent event) {
            //stuff to do on list item click
            return gestureDetector.onTouchEvent(event);
        }
    });

}); //to get click events 

这篇关于ListView 上的 SwipeListener 和 ListView 项目上的 ClickListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆